Home > database >  Convert time from utc to local time js
Convert time from utc to local time js

Time:10-16

I need to take an hour and convert it to local time as such :

const dataDate = '07:08'
const utcDate = new Date(dataDate);
console.log(utcDate)

there are a few problems with my approach

  1. this only works if i add a date too
  2. this converts to utc

I need to only convert the hour to local time, I also need to parse it to something like this :

[parseInt(hour), 0, 0, 0].map(function (x) { return parseInt(x, 10); })

To give more context, I need to create a shareable calendar with a specific schedule, and the user can set the specific hours for some event to be displayed.

CodePudding user response:

If you have access to the full date

Considering your use-case is that of a shareable calendar, I'm assuming you have access to the full UTC date. If that's not the case, skip to the next section.

// The important thing is getting a `Date` object. The timezone in the timestamp
// doesn't really matter at this point. It will be handled internally anyway.
const date = new Date("2011-11-11T07:08:00Z");

Once you have the date object, if all you really want to get is the hour, you can do so with the methods below. But note that you should probably use the same method for getting not only the hours, but any part of the date or time throughout your application.

const utcHour = date.getUTCHours(); //> 7

// For the hour according to the timezone configured in the RUNTIME
// environment (e.g. the user's browser, if running on the client side):
const runtimeHour = date.getHours(); //> 8 (depends on the runtime timezone)

// For an arbitrary timezone, in case you have the user's timezone stored in
// a config you could use the `.toLocaleTimeString()` method.
// Note that this method is VERY slow (~6000 times slower than `.getHours()`
// for example in a quick benchmark I ran in my machine on Node 16). You
// should probably be careful about how often this is being called (e.g. in
// loops or in a frontend component that is frequently updated/rendered).
const tzHour = Number(date.toLocaleTimeString("en", {
  hour: "numeric",              // omit minutes and seconds
  hour12: false,                // force it to be 0-23
  timeZone: "America/Sao_Paulo" // set the user's timezone
})); //> 5

Which one you should use really depends on your exact implementation. You might also want to check this answer that further explains how time zones are handled by Date.

NOTE: the .toLocaleTimeString() method depends on the Intl.DateTimeFormat API. Check Date.prototype.toLocaleTimeString() at MDN for a compatibility table.


Note about manually calculating time offsets

You need the date in order to reliably adjust the time.

If you don't have the date for some reason, you could do so but that would mean quite some work and it would never really be reliable, as you would not be able to factor in Daylight Saving Time adjustments, for example.

Also keep in mind that some timezones operate on fractions of an hour:

  • XX30: Asia/Tehran, Asia/Kabul, Australia/Adelaide...
  • XX45: Australia/Eucla
  • Australia/Lord_Howe has a Daylight Saving Time adjustment of 30 mins;

Depending on the requirements of your application, calculating this manually might not be as simple as you expect. I would recommend to delegate these calculations to the internal Date implementation (as shown in the previous section) instead of trying to adjust the time manually (keep in mind you would have to handle overflows from min → hour → day → month → year).


About parsing the time string

As for the parsing of the time string, you mentioned in your question, you could do something like:

const rawTime = "07:08";
const [hour, minutes, seconds = 0] = rawTime.split(":").map(Number); //> [7, 8, 0]

// or if you only care about the hours
const hour = Number(rawTime.split(":", 1)); //> 7

// or you could also use a quirk of `parseInt()`, as it ignores everything
// starting at the first non-numeric character:
const hour = parseInt(rawTime); //> 7

CodePudding user response:

  1. If you instantiate a new date with new Date() the retuned value is current date/time in UTC timezone.
  2. You can then set a specific hour/minute to that using Date.setHours() and Date.setMinutes().
  3. Finally you can convert that UTC date to local date via Date.toLocaleDateString()

So I would do something like this for your case:

const date = new Date();
const [hour, minute] = '7:28'.split(':')

const options = {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric',
};
date.setHours(hour);
date.setMinutes(minute);

console.log(date.toLocaleDateString('en-US', options));

  • Related