Search code examples
node.jstypescripttimezonemomentjsmoment-timezone

Moment & Timezone convert local time fails


This is in an Ionic based hybrid app on NodeJS.

Trying to convert a local time as specified by a user input to another timezone, yet it fails:

static MTL_local_time_to_server(aDateTime:moment.Moment):moment.Moment{
    console.log(aDateTime.format('MMMM Do YYYY, h:mm:ss a'));

    const localTime:moment.Moment = momenttz.tz(aDateTime, momenttz.tz.guess());
    console.log(localTime.format('MMMM Do YYYY, h:mm:ss a'), momenttz.tz.guess());
    const returnTime:moment.Moment = momenttz(localTime).tz("Europe/Berlin");
    console.log(returnTime.format('MMMM Do YYYY, h:mm:ss a'));
    return returnTime;
}

Prints

April 22nd 2019, 12:00:00 am 
April 22nd 2019, 12:00:00 am America/Los_Angeles 
April 22nd 2019, 9:00:00 am

Solution

  • A few things:

    • You've typed the output of moment.tz as a string, but it's actually a Moment object.

    • When you call JSON.stringify on a Moment object, it returns the output of .toISOString(), which is always in UTC. (The Z indicates UTC in the ISO 8601 format.)

    • It's not clear if your input is a string or a Date object. If it's a string, then the Z indicates UTC, so it will always be interpreted as UTC. If it's a Date object, then the point in time represented by that Date object will be used - which depends on how you constructed the Date object. Either way, the value you're showing is UTC based, not local time.

    • It's not clear exactly what you're trying to accomplish. From your variable names, it would seem like you are trying to convert localDateTime to localTime, which logically would give the same value if they were both "local".

      • If you're trying to convert a value from local time to Berlin time, then:

        moment(yourInput).tz('Europe/Berlin')
        
      • If you're trying to convert a value from Los Angeles time to Berlin time, then:

        moment.tz(yourInput, 'America/Los_Angeles').tz('Europe/Berlin')
        
      • If you're trying to convert a value from UTC to local time, you don't need moment-timezone at all:

        moment.utc(yourInput).local()
        
    • If you need string outputs, then you should call the format function to produce a string. What you showed here looks like you are logging Moment objects not strings.