I'm using Moment.js to parse and format dates in my web app. As part of a JSON object, my backend server sends dates as a number of milliseconds from the UTC epoch (Unix offset).
Parsing dates in a specific timezone is easy -- just append the RFC 822 timezone identifier to the end of the string before parsing:
// response varies according to your timezone const m1 = moment('3/11/2012 13:00').utc().format("MM/DD HH:mm") // problem solved, always "03/11 17:00" const m2 = moment('3/11/2012 13:00 -0400').utc().format("MM/DD HH:mm") console.log({ m1, m2 })
But how do I format a date in a specifc timezone?
I want consistent results regardless of the browser's current time, but I don't want to display dates in UTC.
DD MMM, YYYY
does not work, when I use it like moment.tz("2018-02-15T14:20:00.000+0530", "Asia/Bangkok").format("DD MMM, YYYY")
. Can someone point me in the documentation where I can find all the keys for formatting time when using this api.
"15 Feb, 2018"
. Did you mean to use format string DD MMMM, YYYY
to get "15 February, 2018"
?
As pointed out in Manto's answer, .utcOffset()
is the preferred method as of Moment 2.9.0. This function uses the real offset from UTC, not the reverse offset (e.g., -240 for New York during DST). Offset strings like "+0400" work the same as before:
// always "2013-05-23 00:55"
moment(1369266934311).utcOffset(60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).utcOffset('+0100').format('YYYY-MM-DD HH:mm')
The older .zone()
as a setter was deprecated in Moment.js 2.9.0. It accepted a string containing a timezone identifier (e.g., "-0400" or "-04:00" for -4 hours) or a number representing minutes behind UTC (e.g., 240 for New York during DST).
// always "2013-05-23 00:55"
moment(1369266934311).zone(-60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm')
To work with named timezones instead of numeric offsets, include Moment Timezone and use .tz()
instead:
// determines the correct offset for America/Phoenix at the given moment
// always "2013-05-22 16:55"
moment(1369266934311).tz('America/Phoenix').format('YYYY-MM-DD HH:mm')
A couple of answers already mention that moment-timezone is the way to go with named timezone. I just want to clarify something about this library that was pretty confusing to me. There is a difference between these two statements:
moment.tz(date, format, timezone)
moment(date, format).tz(timezone)
Assuming that a timezone is not specified in the date passed in:
The first code takes in the date and assumes the timezone is the one passed in. The second one will take date, assume the timezone from the browser and then change the time and timezone according to the timezone passed in.
Example:
moment.tz('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss', 'UTC').format() // "2018-07-17T19:00:00Z"
moment('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss').tz('UTC').format() // "2018-07-18T00:00:00Z"
My timezone is +5 from utc. So in the first case it does not change and it sets the date and time to have utc timezone.
In the second case, it assumes the date passed in is in -5, then turns it into UTC, and that's why it spits out the date "2018-07-18T00:00:00Z"
NOTE: The format parameter is really important. If omitted moment might fall back to the Date class which can unpredictable behaviors
Assuming the timezone is specified in the date passed in:
In this case they both behave equally
Even though now I understand why it works that way, I thought this was a pretty confusing feature and worth explaining.
Use moment-timezone
moment(date).tz('Europe/Berlin').format(format)
Before being able to access a particular timezone, you will need to load it like so (or using alternative methods described here)
moment.tz.add('Europe/Berlin|CET CEST CEMT|-10 -20 -30')
.zone() has been deprecated, and you should use utcOffset instead:
// for a timezone that is +7 UTC hours
moment(1369266934311).utcOffset(420).format('YYYY-MM-DD HH:mm')
I was having the same issue with Moment.js. I've installed moment-timezone, but the issue wasn't resolved. Then, I did just what here it's exposed, set the timezone and it works like a charm:
moment(new Date({your_date})).zone("+08:00")
Thanks a lot!
new Date()
constructor. Moment provides everything you'd ever need to parse dates. See Parsing docs.
new Date()
internally), but this is inconsistent across browsers. Instead, you should use provide the expected format as the second argument. Example: moment("12-25-1995", "MM-DD-YYYY")
.
Just came acreoss this, and since I had the same issue, I'd just post the results I came up with
when parsing, you could update the offset (ie I am parsing a data (1.1.2014) and I only want the date, 1st Jan 2014. On GMT+1 I'd get 31.12.2013. So I offset the value first.
moment(moment.utc('1.1.2014').format());
Well, came in handy for me to support across timezones
B
If you pass the timestamp as the parameter to moment()
(e.g if the timezone is Asia/Hong_kong which is +08:00), what I do is:
const localDateTime = moment((item.createdAt.seconds + 8 * 3600) * 1000).format('YYYY-MM-DD HH:mm:ss');
You can Try this ,
Here you can get the date based on the Client Timezone (Browser).
moment(new Date().getTime()).zone(new Date().toString().match(/([-\+][0-9]+)\s/)[1]).format('YYYY-MM-DD HH:mm:ss')
The regex basically gets you the offset value.
Cheers!!
Success story sharing
.zone()
as a getter, which returns minutes from UTC (e.g., returns 300 for New York during standard time)..tz("America/Phoenix")
if you include momentjs.com/timezone as well, however. I've updated the answer with an example.utcOffset()
has nothing to do with DST or time zone rules. It just looks at the moment you've already constructed and gets/sets the number of minutes from UTC. Use the Moment Timezone library with a named timezone ("America/Phoenix") if you want to handle DST and other rules for known time zones.