javascriptmomentjs

MomentJS convert from UTC to desired timezone, not just local


I am using momentjs but having an issue trying to convert a UTC time to a specific timezone (not necessarily local to the current user) that is specified by name 'America/New_York'. This SO question is similar but didn't really help.

My thought process is to create a utc moment obj with the received date from the server and then format that UTC time to the specific timezone for display purposes. A small snippet of how I'm currently approaching this:

var cutoffString = '20170421 16:30:00'; // in utc
var utcCutoff = moment.tz(cutoffString, 'YYYYMMDD HH:mm:ss', '+00:00');
var displayCutoff = 
        moment.tz(utcCutoff.format('YYYYMMDD HH:mm:ss'), 'YYYYMMDD HH:mm:ss', 'America/New_York');

console.log('utcCutoff:', utcCutoff.format('YYYYMMDD hh:mm:ssa Z')); // => utcCutoff: 20170421 04:30:00pm +00:00
console.log('displayCutoff:', displayCutoff.format('YYYYMMDD hh:mm:ssa Z')); // => displayCutoff: 20170421 04:30:00pm +00:00

My assumption here is that displayCutoff would be the utcCutoff time displayed in 'America/New_York' time. But it currently is displays the same time as the utcCutoff object. I also should mention that using .utc() instead of .tz and trying to manipulate the timezone after applying .local() did not work either.

Any help/guidance would be appreciated.


Solution

  • You can use moment.utc since your input is an UTC string. You can use tz to convert your moment object to a given timezone.

    Please note that the tz function converts moment object to a given zone, while you are using moment.tz parsing function that builds a new moment object with the given zone. When you do:

    var displayCutoff = 
        moment.tz(utcCutoff.format('YYYYMMDD HH:mm:ss'), 'YYYYMMDD HH:mm:ss', 'America/New_York');
    

    you are not converting utcCutoff to 'America/New_York' but you are building a new moment object for 20170421 16:30:00 in New York.

    Here an updated version of your code:

    var cutoffString = '20170421 16:30:00'; // in utc
    var utcCutoff = moment.utc(cutoffString, 'YYYYMMDD HH:mm:ss');
    var displayCutoff = utcCutoff.clone().tz('America/New_York');
    
    console.log('utcCutoff:', utcCutoff.format('YYYYMMDD hh:mm:ssa Z')); // => utcCutoff: 20170421 04:30:00pm +00:00
    console.log('displayCutoff:', displayCutoff.format('YYYYMMDD hh:mm:ssa Z')); // => displayCutoff: 20170421 12:30:00pm -04:00
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data-2010-2020.min.js"></script>