Override LocalTZA

# Jonathan Adams (6 years ago)

I understand that an implementation of ECMAScript is expected to determine the local time zone adjustment [1].

This is really convenient -- most of the time. However, it would be great to override this for a given Date object. It doesn't appear that we can at the moment [2] or in ES6.

If we could override this context, we can then take advantage of some of the other native methods such as Date.toString(), Date.getDate() etc. using our preferred, altered LocalTZA rather than users having to build horrible user-land functions [3] and wrestle with daylight savings time adjustments [4].

My particular use-case involves taking dates generated in CST, stored as UTC (this is good) but then I want to offer a list of dates relative to CST, but this is processed in a context with LocalTZA for PST. I can get away with faking it by calculating the difference in timezones and altering the timestamp used to generate a new Date object but, this is going to technically be off at some points in time (DST adjustment for example) and feels wrong/hacky.

-Jon-

[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-15.9.1.7 [2] stackoverflow.com/questions/9369972/can-i-set-the-local-timezone-in-my-browser-via-javascript [3] www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329 [4] esdiscuss/2011-March/013322

# Andrew Paprocki (6 years ago)

The approach I've taken is to implement a native DateTz type which internally stores the UTC Date as well as the Date in the offset specified by either the user or an IANA timezone string. The non-UTC ES Date API then returns the local datetime in the specified timezone. The API is kept to a minimum to avoid adding much on top of the ES Date:

DateTz(msec, offset)
DateTz.inTz(msec, tzstring)

e.g.

var a = new DateTz(Date.now(), -300);
var b = DateTz.inTz(Date.now(), "Asia/Tokyo");

The returned objects simply proxy the public API of ES Date to the internal Date objects, so the above are the only real additions to the API surface.

-Andrew

On Wed, Feb 20, 2013 at 12:52 AM, Jonathan Adams <pointlessjon at me.com>wrote:

I understand that an implementation of ECMAScript is expected to determine the local time zone adjustment [1].

This is really convenient -- most of the time. However, it would be great to override this for a given Date object. It doesn't appear that we can at the moment [2] or in ES6.

If we could override this context, we can then take advantage of some of the other native methods such as Date.toString(), Date.getDate() etc. using our preferred, altered LocalTZA rather than users having to build horrible user-land functions [3] and wrestle with daylight savings time adjustments [4].

My particular use-case involves taking dates generated in CST, stored as UTC (this is good) but then I want to offer a list of dates relative to CST, but this is processed in a context with LocalTZA for PST. I can get away with faking it by calculating the difference in timezones and altering the timestamp used to generate a new Date object but, this is going to technically be off at some points in time (DST adjustment for example) and feels wrong/hacky.

-Jon-

[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-15.9.1.7 [2] stackoverflow.com/questions/9369972/can-i-set-the-local-timezone-in-my-browser-via-javascript [3] www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329 [4] esdiscuss/2011-March/013322


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-------------- next part -------------- An HTML attachment was scrubbed... URL: esdiscuss/attachments/20130220/b393e313/attachment

# Andrew Paprocki (6 years ago)

I suppose I should add that the DateTz approach works only if you embed the IANA "Olson" tzdb with the engine rather than requiring the platform to provide it. Working with different timezones is problematic when going through libc (setting/resetting environment variables), and Windows does not use IANA strings. The DateTz trick only works because it is doing the IANA tzdb calculations itself and accessing its internal two ES Date objects (real UTC timestamp and one with the "shifted" UTC timestamp) via their UTC methods so that the engine itself does not attempt to do any translations.

I would love to see something like DateTz be provided by the spec, but it means a shift to explicitly require native tzdb support by the engine rather than simply relying on the platform to handle conversions for whatever the current user's platform tz setting is. This then means implementations would have to stay up-to-date with tzdb releases (ala Java) to ensure they get proper DST updates. Maybe with the faster release cycles now used this is within the realm of possibility..

# Allen Wirfs-Brock (6 years ago)

What would be the best way to expose the localTZA for you purposes?

At one extreme, we have could add get/setLocalTZA methods to Date.prototype. This would allow the localTZA of any date instance to be dynamically queried or modified (even multiple times). However, this might be more flexibility then is desirable. For example, anytime you pass a date object as a parameter there would be the potential that the local TZA could be modified. Of course, pretty much every other component of a date an be modified so maybe this isn't really a new problem.

Another approach would build off of the subclassability of Date in ES6. localTZA could be defined as a ready only accessor property on Date.prototype that delivers that system default. However, you could define a subclass with a different localTZA;

class CST extends Date {
  get localTZA() {return -6*60*60*1000}
}

then all instances of CST would use the supplied localTZA.

Any preferences? Are there any other values that we need to similarly expose? Perhaps DaylightSavingsTA?

If we're mucking in this area, I wonder if there are other issues we should think about.

One of my concerns is the reliability of these values in long running mobile programs. Consider that I'm running a WebApp on my laptop and have created a bunch of date objects. I then put my laptop to sleep and travel across several timezones before waking it up and resuming the program. What is the localTZA of those preexisting date instances. Was it fixed when they were created or is the default localTZA potentially dynamically updated. What would an application want to happen?

Allen

On Feb 19, 2013, at 9:52 PM, Jonathan Adams wrote:

I understand that an implementation of ECMAScript is expected to determine the local time zone adjustment [1].

This is really convenient -- most of the time. However, it would be great to override this for a given Date object. It doesn't appear that we can at the moment [2] or in ES6.

If we could override this context, we can then take advantage of some of the other native methods such as Date.toString(), Date.getDate() etc. using our preferred, altered LocalTZA rather than users having to build horrible user-land functions [3] and wrestle with daylight savings time adjustments [4].

My particular use-case involves taking dates generated in CST, stored as UTC (this is good) but then I want to offer a list of dates relative to CST, but this is processed in a context with LocalTZA for PST. I can get away with faking it by calculating the difference in timezones and altering the timestamp used to generate a new Date object but, this is going to technically be off at some points in time (DST adjustment for example) and feels wrong/hacky.

-Jon-

[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-15.9.1.7 [2] stackoverflow.com/questions/9369972/can-i-set-the-local-timezone-in-my-browser-via-javascript [3] www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329 [4] esdiscuss/2011-March/013322


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

# Andrew Paprocki (6 years ago)

On Wed, Feb 20, 2013 at 9:51 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

What would be the best way to expose the localTZA for you purposes?

Exposing localTZA at all would only lead to problems, IMO.

class CST extends Date { get localTZA() {return -66060*1000} }

Timezones can not be referred to as static offsets. The only error-free way to deal with timezones is to store the string (e.g. "Asia/Tokyo") and use tzdb when performing conversion into another timezone (in this case, most likely into UTC). UTC offset is a linear function that needs the full datetime as input. Any other representation of it immediately introduces bugs.

program. What is the localTZA of those preexisting date instances. Was it fixed when they were created or is the default localTZA potentially dynamically updated. What would an application want to happen?

Precisely why you need to either store a fixed offset (fixed point in time -- and realize that is what you're doing) or you need to store the full timezone string (in the case of recurring events). Recurring events could not be hacked up with a localTZA modification. If a recurring meeting occurs at 4pm every day in NY, "America/New_York" will needed to be used to compute that in other timezones to avoid errors. Also, you don't even need to get on a plane and fly. For example, if you live in the Middle East, you are in the middle of a work day when the US EST/EDT shifts happen. If you're referring to NY datetimes and using a fixed or precomputed offset instead of treating the conversion as a linear function, there will be errors.

# Jonathan Adams (6 years ago)

Excellent points and ideas here.

I do think it would be extremely valuable to enable the ability to override any Date instance and don't think this is harmful.

Not sure how reasonable/unreasonable requiring tzdb for vendors but seems worth it. Dates are important. Exposing something like

Date.setLocalTimezone('America/Los_Angeles') Date.getLocalTimezone()

and leaving existing Date APIs untouched as well as preventing the guaranteed problems of the natural inclination to pass static offsets seems perfect.

-Jon-

# Andrew Paprocki (6 years ago)

On Wed, Feb 20, 2013 at 11:03 AM, Jonathan Adams <pointlessjon at me.com>wrote:

Date.setLocalTimezone('America/Los_Angeles')
Date.getLocalTimezone()

Since ES Dates represent single points in time (you can't have a time without a date or vice versa), there is no real reason to carry along a timezone string with each Date instance. This is why I took the approach of having a static method to simply construct a shifted Date into a particular timezone. Once the Date object is in that timezone, there is no need to preserve the timezone string because there can only be one valid offset for it. You only need to preserve the timezone string when storing a recurring date/time and ES does not have any native representation of such a thing. Also, sometimes you do need to preserve the static offset because a timezone string is not provided. Parsing a SMTP mail header timestamp is an example of this.

Keeping simple offset storage for a Date makes sense. Then there can be higher level functions which allow you to create Dates in a particular timezone or convert between two timezones by manipulating the stored offset. Yes, someone can resort to manual offset fudgery and create DST bugs, but hiding offset away would prevent people who do know what they're doing what they need.

-Andrew -------------- next part -------------- An HTML attachment was scrubbed... URL: esdiscuss/attachments/20130220/a7b17f3e/attachment

# Gillam, Richard (6 years ago)

Wait a minute. I may be misunderstanding here, but all of this discussion sounds misguided to me.

A Date is intended to represent a specific instance in time, irrespective of time zone. You don't want to go adding time-zone-related fields to the Date object. Time zone becomes important when you're doing calculations on a time (converting it into year/month/day/hour/minute/second, etc.) or when you're converting it to a textual representation for display to the user. This is what the DateTimeFormat class in the ECMAScript internationalization spec is for, and it handles time zone. There's still a lot of work to do there, of course, but let's not break the whole model.

--Rich Gillam Internationalization geek

# Gillam, Richard (6 years ago)

Jon--

The current version of the spec is here: www.ecma-international.org/publications/standards/Ecma-402.htm

What discussion takes place on this standard mostly takes place on this list, and TC39 is ultimately responsible for the standard, although there's an ad-hoc group that does most of the work. I don't remember if TC39's "strawman" pages are open, but there's discussion of the next version of ECMA 402 going on there.

Good luck…

--Rich Gillam Lab126

# Phillips, Addison (6 years ago)

I agree that the tzinfo database and its identifiers should form the basis for ES time zone support. There are some issues with providing support, such as that it means that implementers will need to update several times a year (as time zone rules change).

Setting TimeZone on a Date object might not be the best design, even though that’s sort of the design of Date today. Date values internally are actually timestamps, “incremental time” [1] values---the number of millis since the epoch date in UTC. Making the time zone a property of the date would be confusing, since two incremental times are inherently comparable without reference to LTO (local time offset) or time zone rules.

The problem is that many of the methods of Date expose “field values” within the date—what is the day number or what is the hour number? Where TimeZones need to be used is when transforming dates to/from display. This should apply to the new Intl DateFormat stuff. Maybe adding methods that take a time zone or adding a time zone class might be better? There is the problem that Date today has separate methods that return the local value and the “GMT” value.

Addison

Addison Phillips Globalization Architect (Lab126) Chair (W3C I18N WG)

Internationalization is not a feature. It is an architecture.

[1] www.w3.org/TR/timezone/#incrementaltime

From: Jonathan Adams [mailto:pointlessjon at me.com] Sent: Wednesday, February 20, 2013 8:03 AM To: Andrew Paprocki Cc: es-discuss Subject: Re: Override LocalTZA

Excellent points and ideas here.

I do think it would be extremely valuable to enable the ability to override any Date instance and don't think this is harmful.

Not sure how reasonable/unreasonable requiring tzdb for vendors but seems worth it. Dates are important. Exposing something like

Date.setLocalTimezone('America/Los_Angeles') Date.getLocalTimezone()

and leaving existing Date APIs untouched as well as preventing the guaranteed problems of the natural inclination to pass static offsets seems perfect. -Jon-

On Feb 20, 2013, at 7:03, Andrew Paprocki <andrew at ishiboo.com<mailto:andrew at ishiboo.com>> wrote:

On Wed, Feb 20, 2013 at 9:51 AM, Allen Wirfs-Brock <allen at wirfs-brock.com<mailto:allen at wirfs-brock.com>> wrote:

What would be the best way to expose the localTZA for you purposes?

Exposing localTZA at all would only lead to problems, IMO.

class CST extends Date { get localTZA() {return -66060*1000} }

Timezones can not be referred to as static offsets. The only error-free way to deal with timezones is to store the string (e.g. "Asia/Tokyo") and use tzdb when performing conversion into another timezone (in this case, most likely into UTC). UTC offset is a linear function that needs the full datetime as input. Any other representation of it immediately introduces bugs.

program. What is the localTZA of those preexisting date instances. Was it fixed when they were created or is the default localTZA potentially dynamically updated. What would an application want to happen?

Precisely why you need to either store a fixed offset (fixed point in time -- and realize that is what you're doing) or you need to store the full timezone string (in the case of recurring events). Recurring events could not be hacked up with a localTZA modification. If a recurring meeting occurs at 4pm every day in NY, "America/New_York" will needed to be used to compute that in other timezones to avoid errors. Also, you don't even need to get on a plane and fly. For example, if you live in the Middle East, you are in the middle of a work day when the US EST/EDT shifts happen. If you're referring to NY datetimes and using a fixed or precomputed offset instead of treating the conversion as a linear function, there will be errors.

# Norbert Lindenberg (6 years ago)

The internationalization ad-hoc of TC 39 has already decided that edition 2 of the ECMAScript Internationalization API will support IANA time zone names in DateTimeFormat. Implementations will need to include best available information on all time zones or use equivalent operating system APIs.

I agree with Rich and Addison that adding a time zone to Date instances would only create confusion. I think the best way to add general support for time zones that's not tied to formatting would be methods that convert between incremental time (a Date instance) and field-based time. Under the covers, the Internationalization API spec already includes one direction as an abstract operation: www.ecma-international.org/ecma-402/1.0/index.html#ToLocalTime Note that this operation also takes a calendar - this hasn't come up on this thread yet, but is required because day/month/year values are always relative to a calendar.

Jon, Andrew: would a method similar to that operation address your needs?

Norbert

# Jonathan Adams (6 years ago)

Absolutely. Now that I know this exists I completely agree with you. Would rather not muck up the Date api any more than it already is and the separation makes more sense.

Thanks, all.

-Jon-

# Andrew Paprocki (6 years ago)

On Wed, Feb 20, 2013 at 6:08 PM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

Jon, Andrew: would a method similar to that operation address your needs?

I agree that the conversion functionality is needed outside of formatting, but the issue for me is more complex. We have a vocabulary type consisting of [serial datetime, offset] used throughout our stack -- including both data services taking input from script and delivering output to script as well as native objects bound into script which use this vocabulary type in their API. In all those cases we don't have a way to pass individual fields. What is being proposed should be all that is needed for the browser world. I already modify the engine to override localTZA anyway because the "platform" timezone used by script is not the same as the timezone of the OS/user the engine is running as, so I'm used to being an exception.. :)