Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Momentjs timezone - getting date at time in specific timezone

I am attempting to create a date from a UTC base in a user's specific timezone, in this case "America/Los Angeles" using momentjs/momentjs timezone. However, I'm not getting the results I expect:

var tempDate = moment(1448841600000); //moment("2015-11-30"); //monday 11/30 in UTC
var adjustedStart = moment.tz(tempDate, "America/Los_Angeles");
adjustedStart.hour(9);
adjustedStart.minute(30);
console.log("adjustedStart in milliseconds:" + adjustedStart.valueOf());

The console output is 1448875800000 which is 11/30/15 9:30AM in UTC/GMT, I was expecting 1448904600000 which is 11/30/15 9:30AM in Pacific Coast time. How can I translate this start date to the right time in the user's timezone?

like image 440
Eric H Avatar asked Dec 08 '15 00:12

Eric H


2 Answers

Yes, 1448841600000 is the date you said:

moment(1448841600000).utc().format()
// "2015-11-30T00:00:00+00:00"

But that is a day earlier in Pacific time

moment(1448841600000).tz('America/Los_Angeles').format()
// "2015-11-29T16:00:00-08:00"

When you adjust it to 9:30 pacific, it's on the 29th, not the 30th.

moment(1448841600000).tz('America/Los_Angeles').hour(9).minute(30).format()
// "2015-11-29T09:30:00-08:00"

When you call valueOf, the result is:

moment(1448841600000).tz('America/Los_Angeles').hour(9).minute(30).valueOf()
// 1448818200000

This is the correct value, however it's different than the one you provided. However, it is indeed what I get when I run your code as well.

Screenshot from Chrome debug window, with your exact code:

screenshot

Also, in comments you wrote:

//moment("2015-11-30"); //monday 11/30 in UTC

Actually, that would be in local time, not UTC. If you wanted UTC, you'd use:

moment.utc("2015-11-30")

Though it's unclear to me whether you are using this string input or the numeric timestamp.

If what you are asking is that you want the UTC date to be treated as if it were local and then have an arbitrary local time applied - that is a somewhat strange operation, but it would go something like this:

var tempDate = moment.utc(1448841600000);
var adjustedStart = moment.tz([tempDate.year(), tempDate.month(), tempDate.date(), 9, 30],
                                                                  "America/Los_Angeles");
console.log("adjustedStart in milliseconds:" + adjustedStart.valueOf());
// adjustedStart in milliseconds:1448904600000

This gives the value you asked for, but to me - this is a smell that something is wrong with the expectation. I'd look a lot closer at the requirement and the other parts of the system.

like image 172
Matt Johnson-Pint Avatar answered Nov 09 '22 06:11

Matt Johnson-Pint


From http://momentjs.com/docs/:

moment#valueOf simply outputs the number of milliseconds since the Unix Epoch

It is important to note that though the displays differ above, they are both the same moment in time.

var a = moment();
var b = moment.utc();
a.format();  // 2013-02-04T10:35:24-08:00
b.format();  // 2013-02-04T18:35:24+00:00
a.valueOf(); // 1360002924000
b.valueOf(); // 1360002924000

So it shouldn't differ for different timezones.

You should use adjustedStart.format(); to see the difference

like image 30
jonasnas Avatar answered Nov 09 '22 07:11

jonasnas