Kos
Kos

Reputation: 72241

How to format a date in a given timezone in Javascript?

I have an ISO timestamp with a timezone:

> let datestring = "2016-07-15T09:20:32.730689-04:00";

I'd like to format it to a human-readable format like "Jul 15 2016, 09:20" while keeping the timezone.

I tried this first:

> new Date(datestring).toString()
"Fri Jul 15 2016 15:20:32 GMT+0200 (CEST)"
> new Date(datestring).toISOString()
"2016-07-15T13:20:32.730Z"

Of course this can't do what I wanted because new Date() only stores milliseconds since epoch and the -04:00 timezone was dropped after parsing. Okay.

I also learned that:

Neither looks helpful, so let's look into the libraries.


Next thing I tried was moment:

> moment(datestring)._tzm
-240

okay, Moment doesn't lose my date's timezone! That's nice, I hope I can use a moment object like an aware datetime object in Python. So how do I format it?

> moment(datestring).toString()
"Fri Jul 15 2016 15:20:32 GMT+0200"
> moment(datestring).toISOString()
"2016-07-15T13:20:32.730Z"

Oh, these look like Moment just forwarded the request to the datetime. Let's try something then:

moment(datestring).format("MMM D YYYY, HH:mm")
"Jul 15 2016, 15:20"

The format looks nice but what's this 15:20? Oh, that's my local time. Looks like format() also assumes that I wanted to ignore the datetime's parsed timezone offset and I'd prefer my local timezone. No luck here.

But there's moment().utcOffset that allows me to specify a given timezone offset:

> let m = moment(datestring)
> m.utcOffset(m._tzm).format("MMM D YYYY, HH:mm")
"Jul 15 2016, 09:20"

Yay, it works! However I didn't see this _tzm documented anywhere, looks like I'm messing with moment internals now.


What's the "by the book" way to achieve this?

Could this be done in vanilla js without moment, assuming I'm fine with iso format?

Upvotes: 0

Views: 511

Answers (1)

David Sherret
David Sherret

Reputation: 106640

I think you are looking for the parseZone function:

let datestring = "2016-07-15T09:20:32.730689-04:00";
let m = moment.parseZone(datestring);

m.hour();                      // 9
m.format("MMM D YYYY, HH:mm"); // "Jul 15 2016, 09:20"

By default moment will use the local time zone, but if you use parseZone then it will use the input string's time zone.

Upvotes: 1

Related Questions