Search code examples
timezonemomentjsutcdatetime-conversion

moment-timezone format doesn't return the expected result


Using the tz() function from moment-timezone as follow:

moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format()
//returns '2017-10-15T13:53:43+08:00'

moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format('h:m A')
//I expect to return '9:53 PM' but it returns '1:53 PM'

Ultimately, I want to apply the fromNow() function to format the result. But when I apply it, it uses the initial timestamp and ignore the timezone applied.

moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').fromNow()
//I expect to return '1 min ago' when actual time is 13:54 UTC (21:54 in HK) but it returns '8 hours ago'

What am I doing wrong here?


Solution

  • When you do:

    moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong');
    

    You're creating a date/time that corresponds to October 15th 2017, at 1:53 PM in Hong Kong - which, in turn, corresponds to 2017-10-15T05:53:43Z (5:53 AM in UTC).

    When you call the format() function:

    moment.tz('2017-10-15 13:53:43','Asia/Hong_Kong').format();
    

    It returns:

    2017-10-15T13:53:43+08:00

    The +08:00 part is just the UTC offset - it just tells that Hong Kong is 8 hours ahead UTC. But 2017-10-15T13:53:43+08:00 (1:53 PM in Hong Kong) is exactly the same instant as 2017-10-15T05:53:43Z (5:53 AM in UTC). That's why fromNow(), when the current time is 13:54 UTC, returns 8 hours.

    If you want the date/time that corresponds to 1:53 PM in UTC, you should use the utc() function:

    // October 15th 2017, 1:53 PM in UTC
    moment.utc('2017-10-15 13:53:43');
    

    Now, when the current time is 13:54 UTC, fromNow() will return 1 minute (because the date/time represents 1:53 PM in UTC).

    To convert this to Hong Kong timezone, just use the tz() function:

    // convert 1:53 PM UTC to Hong Kong timezone (9:53 PM)
    moment.utc('2017-10-15 13:53:43').tz('Asia/Hong_Kong').format('h:m A');
    

    This will convert 1:53 PM UTC to Hong Kong timezone (resulting in 9:53 PM):