DaniOcean
DaniOcean

Reputation: 606

How to create time in a specific time zone with moment.js

I have this backend that sends me a pre formatted time in a set time zone, but without any information for the said time zone. The strings are like: "2013-08-26 16:55:00".

I can create a new moment.js instance with this string:

var time = moment("2013-08-26 16:55:00") //this creates time in my tz

but this will only create an instance in my own time zone.

Moment.js have a plugin that can create instances of the object in specific time zones and it works great, but I can't say what time I want the object to point to.

If I'm in New York and I do this:

var time = moment("2013-08-26 16:55:00").tz("America/Los_Angeles");

the resulting time will be 13:55 instead of 16:55 but in LA.

What I want is to create an instance that will say 16:55, but in LA time.

The reason I'm asking is because I want to do this:

var now = moment.tz("America/Los_Angeles");
var end = moment("2013-08-26 16:55:00"); //plus something to convert LA time

var timeLeft = end.diff(now, "minutes");

Is there a way to do that?

Upvotes: 46

Views: 41157

Answers (6)

Vaha
Vaha

Reputation: 2587

You can set the moment's timezone during initializations without using .tz() function directly, like next:

        moment = include();
        const someMomentObj= moment();
        const someOtherMomentObj = moment();
        const yourTimezone = 'Africa/Accra';
        const momentObj = moment(
            `${someMomentObj.format('YYYY-MM-DD')} ${someOtherMomentObj} ${yourTimezone}`,
            'YYYY-MM-DD HH:mm z'
        );

In this case 'yourTimezone' constant will correspond to 'z' symbol of 'YYYY-MM-DD HH:mm z' input template. In same time you will not change initialized object's timezone, but just properly parse it as a input value.

Upvotes: 0

Nishith
Nishith

Reputation: 1118

I had a similar issue for which i had to use New York based time so i had to consider for daylight savings. I tried using the above few answers but wasn't able to get it working. Then I solved my issue like the below code

import moment from 'moment-timezone'

const time = timestamp
const offset = moment.tz.zone('America/New_York')?.parse(time)
const date = moment(time).add(offset, 'minutes').toISOString()

or you can do this way which will consider the time offset on its own when you display locally.

const time = moment.tz(timestamp, 'America/New_York')
const localtz = moment.tz.guess()
const date = time.clone().tz(localtz)

this gives you an ISO string which you can use as below

moment(date).local().format('dddd, MMM DD YYYY, hh:mm A')

or in whatever format you would like to display it

Upvotes: 1

Caius Jard
Caius Jard

Reputation: 74595

Just to make something abundantly clear, that is implied in other answers but not really stated:

  • You absolutely must either
    • use ISO8601 as your date format or
    • specify the format your string is in

.. when using the .tz(string datetime, [string format,] string zone) function, if you want moment to interpret the datetime argument you give to be in the zone you give. If you omit format, be sure to pass an ISO8601 formatted string


For 2 days I went round in circles, because my API was delivering a time string like "03 Feb 2021 15:00" and sure, it parsed OK, but it always used the timezone from my local machine, then converted to the timezone I gave:

//this always resulted in "2021-02-03 10:00 EST" if run on a machine in UTC
moment.tz("03 Feb 2021 15:00", "America/Indianapolis").format("YYYY-MM-DD HH:mm z")

This was massively confusing: the parsing was clearly working fine, because the date was right but the time was always wrong by however many hours there were between the machine and the given zone string

Switching to ISO format input worked:

//this always resulted in "2021-02-03 15:00 EST" if run on a machine in UTC
moment.tz("2021-02-03 15:00", "America/Indianapolis").format("YYYY-MM-DD HH:mm z")

As did declaring:

//this always resulted in "2021-02-03 15:00 EST" if run on a machine in UTC
moment.tz("03 Feb 2021 15:00", "DD MMM YYYY HH:mm", "America/Indianapolis").format("YYYY-MM-DD HH:mm z")

I hope this saves someone some time

Upvotes: 2

JOG
JOG

Reputation: 5640

install moment-timezone

> npm install moment-timezone

Or see https://momentjs.com/timezone/docs/

.tz(string, string)

moment.tz("2020-01-02 13:33:37", "Iran/Tehran")

Upvotes: 2

timmcliu
timmcliu

Reputation: 1879

If you want to calculate everything in a specific timezone you want to set the default time zone using

A) moment.tz.setDefault("America/Los_Angeles");

For my use case (in a node.js project) I just set it right after requiring the moment modules like so:

let moment = require('moment');
require('moment-timezone');
moment.tz.setDefault("America/Los_Angeles");

All calls to moment() thereafter will create the time in the "America/Los_Angeles" setting, which is NOT the same as using:

B) moment.tz("2017-03-04 00:00", "America/Los_Angeles")

OR

C) moment("2017-03-04 00:00").tz("America/Los_Angeles")

both of which would create the moment object in UTC time (unless you already changed the default), and then convert it to be the Los Angeles timezone.

Running B or C above in the browser console yields:

_d: Fri Mar 03 2017 16:00:00 GMT-0800 (PST)
_i: "2017-3-4 00:00"

Notice _d shows March 3 4:00pm; this is because the moment object is created with March 4 12:00am in UTC time, then converted to Pacific timezone, which is 8 hours behind/the previous day.

source: http://momentjs.com/timezone/docs/#/using-timezones/default-timezone/

Upvotes: 8

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241420

In most cases, you can simply do this:

moment.tz("2013-08-26 16:55:00", "America/Los_Angeles")

If you require input other than ISO8601, then specify the format string as the second parameter, and the time zone as the third:

moment.tz("8/26/2013 4:55 pm", "M/D/YYYY h:mm a", "America/Los_Angeles")

And if you need to use moment's "strict parsing" mode, then that goes in the third parameter, and the time zone moves to the fourth position:

moment.tz("8/26/2013 4:55 pm", "M/D/YYYY h:mm a", true, "America/Los_Angeles")

Upvotes: 62

Related Questions