Search code examples
node.jsmomentjsutcmoment-timezone

momentJS: Getting wrong timestamp from date in a different timezone


There is one time input i.e. start_time

I am trying to get timestamp in milliseconds for these inputs

let start_time = "17:05:00";
var start_date_moment = moment(start_time, "HH:mm:ss");
console.log(start_timestamp);
output is -> moment("2019-04-24T17:05:00.000")

This output remains same on server and local

But when I am trying to get unix timestamp in milliseconds in the same way

var start_timestamp = moment(start_time, "HH:mm:ss").valueOf();

On server at different timezone

console.log(start_timestamp);//1556125500000
console.log(moment(start_timestamp/1000).format('YYYY-MM-DD HH:mm:ss'); //2019-04-24 17:05:00

On local

console.log(start_timestamp);//1556105700000
console.log(moment(start_timestamp/1000).format('YYYY-MM-DD HH:mm:ss'); //2019-04-24 22:35:00

This start_timestamp value is different on local and server. But timestamp shouldn't change with timezone, it should remains same for all timezones. Please help me with this.

How to get the correct and same value at both places. I got this link some what related to this https://github.com/moment/moment/issues/2035

There is no issue with dates any particular format, issue is only with timestamp.


Solution

  • You need to take the offset into consideration when using moment (using timezones moment.js). Since no offset was passed in the input, the moment will be based on the time zone of the computer the code is running on, hence the different values..

    Example:

    var a = moment.tz("2013-11-18 11:55", "Asia/Taipei");
    var b = moment.tz("2013-11-18 11:55", "America/Toronto");
    
    a.format(); // 2013-11-18T11:55:00+08:00
    b.format(); // 2013-11-18T11:55:00-05:00
    
    a.utc().format(); // 2013-11-18T03:55Z
    b.utc().format(); // 2013-11-18T16:55Z
    

    If you change the time zone of a moment object using moment-timezone only affects the value of the local time. It does not change the moment in time being represented, and therefore does not change the underlying timestamp.

    A Unix Timestamp is always based on UTC - you can see it as the same timestamp at any given location in the world.

    Edit:

    If you use utcOffset you should pass an integer:

    Example:

    moment.utc("2015-10-01 01:24:21").utcOffset("-240").format('YYYYMMDD HHmmss ZZ')
    // "20151001 012421 +0000"
    
    moment.utc("2015-10-01 01:24:21").utcOffset(-240).format('YYYYMMDD HHmmss ZZ')
    // "20150930 212421 -0400"
    

    MomentJS allows offset-arguments to be passed as string, but it expects the string to be in one of the ISO8601 formats: [+/-]HH:mm or [+/-]HHmm.

    To avoid this all together you could, if known, pass the location as an argument like

     moment.tz(start_time, "HH:mm:ss", "Asia/Kolkata").valueOf();
    

    as mentioned in the first example above..