kinetic
kinetic

Reputation: 63

Converting a date, time and offset into an ISO8601 DateTime using moment.js and moment timezone

I am processing some itinerary data where the times and dates are all provided in the local timezone. I am adding this data to a database where I'd like to store all of the dates in UTC, with the proper timezone offset. I'm trying to process these dates with moment.js.

The input string for date/time is formatted like this 2020-07-12 13:00 and the timezone is in this format Europe/Amsterdam.

I want to end up with a string like:

2020-07-12T11:00:00+02:00

The trouble I'm having, is that moment converts my input time to either local time or utc if I use the .utc() method.

This code is getting me the correct result, but I don't understand why and I'm not sure if I can rely on its accuracy:

var offset = moment.tz(`Europe/Amsterdam`).utcOffset();
var m = moment(`2020-07-12 13:00`, 'YYYY-MM-DD HH:mm').utc().subtract(240 + offset + offset, 'minutes').utcOffset(offset); // (240 is my own UTC offset)

How can I simply input a date, time and timezone and end up with a correct ISO8601 DateTime?

Upvotes: 2

Views: 2020

Answers (1)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241495

If you are already using Moment and Moment-TimeZone in your app, then you can simply do the following:

const m = moment.tz('2020-07-12 13:00', 'YYYY-MM-DD HH:mm', 'Europe/Amsterdam');
m.format() //=> "2020-07-12T13:00:00+02:00"

However, the Moment team recommends using Luxon for new development. The equivalent is:

const dt = luxon.DateTime.fromFormat('2020-07-12 13:00', 'yyyy-MM-dd HH:mm', { zone: 'Europe/Amsterdam'});
dt.toISO()  //=> "2020-07-12T13:00:00.000+02:00"

The only difference being that milliseconds are included. You can use a different formatting function if you prefer a different output.

The main benefit of Luxon is that it uses the built-in time zone functionality provided by the ECMAScript Internationalization API, whereas Moment-Timezone bundles its own time zone data - which can be quite large.

Also, note that in your question by asking for 2020-07-12T11:00:00+02:00 you seem to be misunderstanding the ISO 8601 format. In that format, the time presented is the local time. Thus, it should be 13:00, not 11:00. The +02:00 means, "this was the offset from UTC for this local time". (It doesn't mean that you apply the offset to get the local time.)

Upvotes: 1

Related Questions