Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

moment.js, timezones and daylight savings

I return a list of UTC dates/times from a .Net service, formatted like so:

"2013-07-09 19:48:07 +00:00".

On the client, I convert each of these string values into a corresponding UTC-based moment, like so

var fooUtc = new moment.utc(serverDateTimeString)

On the page, there is a droop-down containing a list of time-zones that the user can change. These are tied to a collection of time-zone objects like the following:

{
    id: "Central Standard Time",
    label: "(UTC-06:00) Central Time (US & Canada)",
    observesDaylightSavings: true,
    baseUtcOffset: {
        asHours: -6,
        asMinutes: -360,
        asText: "-06:00"
}

I then display each moment passing in the selected time-zone offset, like so:

fooUtc.local().zone(selectedTimeZone.baseUtcOffset.asMinutes).format()

However, the result does not take into account daylight savings, as the timezone data coming from .Net does not differentiate between dst and non dst offsets.

Is there a way to make this work with moment.js or the new moment-timezone bits? I think it could be possible if I could map the standard UTC offset names (ex: "Central Standard Time") to a given timezone's Olson DB identifier (ex: "America/Chicago"), but if there is an easier way, please let me know.

like image 327
Joshua Barker Avatar asked Jul 09 '13 23:07

Joshua Barker


People also ask

Does moment timezone account for daylight savings?

Event moment-timezone (at moment of writing 0.5. 37) doesn't support DST info (i.e is the clock officially in DST at a given moment or not), so for things to get better some new stuff (and tzdata bundling) has to happen in moment-timezone.

How does Javascript handle Daylight Savings moment?

js isDST() Function. It is used to check daylight saving time in Moment. js using the isDST() function.

Does Javascript date handle Daylight Savings?

The answer is Yes. If we are considering New York, USA, then during Daylight Saving, the offset is -4, whereas it would otherwise be -5. There's a solution for this as well: an additional function while obtaining destination city's UTC offset.

Does getTimezoneOffset account for daylight savings?

The getTimezoneOffset method returns a greater value during Standard Time, than during Daylight Saving Time. The Math. max() function takes two or more comma-separated numbers and returns the max value.


1 Answers

You should explore using Noda Time on the .Net side, and moment-timezone on the client, passing the IANA/Olson time zone id.

If you want to stick to the Windows time zone ids in your drop-down list, then you can do conversions with the CLDR data embedded in Noda Time. I have documented how to do it in this post: How to translate between Windows and IANA time zones?

But the better solution would be to avoid the Windows zones all together. You can populate a list of IANA/Olson ids using the technique I describe in this post: How should I populate a list of IANA / Olson time zones from Noda Time?

Better yet, you can replace your drop-down list with a control (inline or modal) that displays a map of the world, so your users can easily select their time zone. The best control for this that I have seen is this one, but there are a few others out there also.

If you can deal strictly in IANA/Olson zones, then there's no need for conversion. You can give up the Windows TimeZoneInfo object and just use Noda Time instead. If you want, you can replace just your time zone conversion functions and leave the rest intact. Or, you could go all-out and replace all of your DateTime and DateTimeOffset uses with Noda Time types. It's up to you.

like image 79
Matt Johnson-Pint Avatar answered Oct 10 '22 14:10

Matt Johnson-Pint