Time zone offsets for any time zone, possible change to Date functionality (i18n)

# Nebojša Ćirić (12 years ago)

We need to support conversion between:

{Y, M, D, H, M, S, AnyTimeZone*} <=> {UTC Epoch millis}

*AnyTimeZone - doesn't have to be system one, supports IANA tz format.

We currently implement that by using the Javascript Date object's UTC representation and TimeZone knowledge which can provide the offset from UTC at a point in time.

Problem: timezone data needs to be synced, requires network roundtrip + js evaluation + object creation in the critical path of the initial load. JSON payload: ~300k uncompressed, ~30k compressed. 300k data set represents only span of couple of years.

Since we (i18n) already have timezone data for date formatting, we could do what we did for Date.prototype.toLocaleDateString and extend say Date.prototype.getTimezoneOffset method to support timezone parameter.

Internet has lots of questions related to this topic, and answers are not 100% satisfactory.

We could discuss this on our next i18n ad-hoc meeting (tentative date 2013-04-19, 9:30am) if we have time, but I think it's a good question for the main group too.

# Domenic Denicola (12 years ago)

From: Nebojša Ćirić [cira at google.com]

Since we (i18n) already have timezone data for date formatting, we could do what we did for Date.prototype.toLocaleDateString and extend say Date.prototype.getTimezoneOffset method to support timezone parameter.

This sounds amazing. Please do this.

To clarify,

var tzo = dateObj.getTimezoneOffset("America/New_York")

would give the minutes offset of the America/New_York timezone, from UTC, at the point in time designated by dateObj. Right?

# Nebojša Ćirić (12 years ago)

That's correct. We may need reverse too - for given UTC epoch milliseconds (or minutes after UTC Date) tell me what the date components would be in a given timezone.

2013/4/9 Domenic Denicola <domenic at domenicdenicola.com>

# Domenic Denicola (12 years ago)

From: Nebojša Ćirić [cira at google.com]

That's correct. We may need reverse too - for given UTC epoch milliseconds (or minutes after UTC Date) tell me what the date components would be in a given timezone.

Hmm, so:

var date = new Date(utcMilliseconds);

var monthInNewYork = date.getMonth("America/New_York");
var monthInParis = date.getMonth("Europe/Paris");

? And I guess then date.getUTCMonth() is just an alias for date.getMonth("Etc./UTC"). Seems good!!

# Nebojša Ćirić (12 years ago)

Sounds about right. We just need to agree it's worth doing it, and in which version of ES and i18n we wanna do it. If we keep tz parameter optional, we would avoid additional data burden on lite JS implementations.

2013/4/9 Domenic Denicola <domenic at domenicdenicola.com>

# Nebojša Ćirić (12 years ago)

Wrote a short strawman - globalization:timezoneoffsets

# Nebojša Ćirić (12 years ago)

How about if the [timezone] parameter would only be passed at the construction of the Date object? That would (perhaps) allow a user to centralize timezone validation as well.

For example:

var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0);
var date = Date.withTimeZone("America/Los_Angeles", 1365545496000);
date.getHours(); // 15
date.getUTCHours(); // 22

My 2c, Sorin

I'll add this as a second option to the strawman.

# Norbert Lindenberg (12 years ago)

On Apr 9, 2013, at 11:30 , Nebojša Ćirić wrote:

We need to support conversion between: {Y, M, D, H, M, S, AnyTimeZone*} <=> {UTC Epoch millis}

*AnyTimeZone - doesn't have to be system one, supports IANA tz format.

I proposed one direction of this mapping a while ago as "public API for ToLocalTime": ecmascript#698

Note that the calendar is also required input along with the time zone, and that for a mapping from field-based time to incremental time you also need the era and whether the time is in DST (for the one hour per year that occurs twice when clocks fall back from daylight saving time to standard time). Throwing in the weekday, which is optional but often desired output, the complete mappings are:

{calendar, time zone, time value} => {weekday, era, year, month, day, hour, minute, second, inDST}

and {calendar, time zone, era, year, month, day, hour, minute, second, inDST} => time value

Since we (i18n) already have timezone data for date formatting, we could do what we did for Date.prototype.toLocaleDateString and extend say Date.prototype.getTimezoneOffset method to support timezone parameter.

I seem to remember that TC 39 had reservations against adding arguments to existing methods - maybe Mark Miller can recall the reasons? For localeCompare and toLocaleString we got away with it because they've been documented all along as likely adding an additional argument in the future.

Norbert

# Norbert Lindenberg (12 years ago)

On Apr 9, 2013, at 15:23 , Nebojša Ćirić wrote:

I'll add this as a second option to the strawman.

2013/4/9 Sorin Mocanu <sorinmocanu at google.com> Thank you Nebojša. How about if the [timezone] parameter would only be passed at the construction of the Date object? That would (perhaps) allow a user to centralize timezone validation as well.

For example: var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0); var date = Date.withTimeZone("America/Los_Angeles", 1365545496000); date.getHours(); // 15 date.getUTCHours(); // 22

Sorin Mocanu, Software Engineer Google Switzerland GmbH | Brandschenkestrasse 110 | Zurich, Switzerland | 8002 Zurich

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray. Also, I'm not sure what to make of the second example - how is the time zone used in the interpretation of the time value, which should be in UTC? And why does getHours return 15, seven hours behind UTC, when you're in Switzerland?

Norbert

# Sorin Mocanu (12 years ago)

Sorry for not having better explained my suggestion. var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0); would create a Date object with a local time for "America/Los_Angeles", regardless of my computer's timezone. The difference is that calls to date.getHours would not be local to the system timezone, but to the timezone passed in the constructor. Hence getHours would return 15 since the "local time" is not my computer's time, but America/Los_Angeles.

If you feel that this is a stretch of the current contract AND adding arguments to existing methods is discouraged, would you rather suggest to add new methods which are timezone aware? Such as: getTzHours("America/Los_Angeles")

Then for var d = new Date(1365627600000) ran on a computer with the local timezone of Europe/Zurich the following would be true: d.getHours() == 23; // The local time in CEST d.getUTCHours() == 21; // The UTC time d.getTzHours("America/Los_Angeles") == 14 // The time in PDT

Thanks!

Sorin Mocanu, Software Engineer Google Switzerland GmbH | Brandschenkestrasse 110 | Zurich, Switzerland | 8002 Zurich | Identifikationsnummer: CH-020.4.028.116

# Claude Pache (12 years ago)

Le 15 avr. 2013 à 09:27, Sorin Mocanu <sorinmocanu at google.com> a écrit :

Hi Norbert,

Sorry for not having better explained my suggestion. var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0); would create a Date object with a local time for "America/Los_Angeles", regardless of my computer's timezone.

Although I guess what you mean, I think it doesn't make sense to say "... create a Date object with a local time ...", since a Date object does not represent a local time. Alternatively, I may have misunderstood your formulation.

Anyway, it would be clearer if you say the following:

  • Date.withTimeZone() would create a Date object from a local time, etc.; and
  • a Date object would internally hold not only a given point in time (more precisely, a millisecond offset relative to 1970-01-01 00:00:00 UTC), but also an optional timezone information which will be used for d.getHours() et al.

— Claude

# Dean Landolt (12 years ago)

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

On Apr 9, 2013, at 15:23 , Nebojša Ćirić wrote:

I'll add this as a second option to the strawman.

2013/4/9 Sorin Mocanu <sorinmocanu at google.com> Thank you Nebojša. How about if the [timezone] parameter would only be passed at the construction of the Date object? That would (perhaps) allow a user to centralize timezone validation as well.

For example: var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0); var date = Date.withTimeZone("America/Los_Angeles", 1365545496000); date.getHours(); // 15 date.getUTCHours(); // 22

Sorin Mocanu, Software Engineer Google Switzerland GmbH | Brandschenkestrasse 110 | Zurich, Switzerland | 8002 Zurich

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no** impact on a date's underlying value, just on the behavior of its locale methods. If you want to alter the timezone used for locale methods on a specific instance just set this property. You can get a Date constructor pinned to a specific timezone through subclassing. Weak implementations lacking proper tz support would freeze this property on fresh dates.

All the while nothing about Date objects and their methods would change -- it would be fully backward compatible. With a little more thought it could be made polyfillable (perhaps it doesn't need to be a symbol at all, if a suitable name can be found that is unlikely to collide with existing libs). What's not to like? More specifically, in what way is the current state of affairs better?

[snipped the rest]

# Claude Pache (12 years ago)

Le 15 avr. 2013 à 14:43, Dean Landolt <dean at deanlandolt.com> a écrit :

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg <ecmascript at lindenbergsoftware.com> wrote:

On Apr 9, 2013, at 15:23 , Nebojša Ćirić wrote:

I'll add this as a second option to the strawman.

2013/4/9 Sorin Mocanu <sorinmocanu at google.com> Thank you Nebojša. How about if the [timezone] parameter would only be passed at the construction of the Date object? That would (perhaps) allow a user to centralize timezone validation as well.

For example: var date = Date.withTimeZone("America/Los_Angeles", 2013, 3, 9, 15, 11, 0); var date = Date.withTimeZone("America/Los_Angeles", 1365545496000); date.getHours(); // 15 date.getUTCHours(); // 22

Sorin Mocanu, Software Engineer Google Switzerland GmbH | Brandschenkestrasse 110 | Zurich, Switzerland | 8002 Zurich

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no impact on a date's underlying value, just on the behavior of its locale methods. If you want to alter the timezone used for locale methods on a specific instance just set this property. You can get a Date constructor pinned to a specific timezone through subclassing. Weak implementations lacking proper tz support would freeze this property on fresh dates.

All the while nothing about Date objects and their methods would change -- it would be fully backward compatible. With a little more thought it could be made polyfillable (perhaps it doesn't need to be a symbol at all, if a suitable name can be found that is unlikely to collide with existing libs). What's not to like? More specifically, in what way is the current state of affairs better?

[snipped the rest]


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

Hi Dean,

What would be the behaviour of the following steps:

(1) store a Date object d locally using IndexedDB; (2) change the timezone of the operating system, and maybe restart the browser; (3) retrieve the date d stored in step 1.

In what timezone will be the retrieved date? and in what timezone should it be?

I have not try the experiment, but my educated guess is that (1) the value ofd.getUTCHours() would remain invariant and (2) the value of d.getHours() would vary according to the change operated in step (2). In other words, getHours, setHours, etc. do have (unfortunately) an implicit parameter, which is the timezone provided by the system, but that parameter is not part of the Date instance.

Now, do you propose that d should hold its timezone information, so that it would remain in the old timezone, but dCloned = new Date(d) would be in the new timezone? That seems hazardous to me.

# Dean Landolt (12 years ago)

Perhaps I wasn't clear: I was proposing the timezone property as purely informative for the locale methods. The Date constructor used to revive the IDB value will dictate the date's timezone, so no, the cloned date wouldn't carry its timezone with it. However, in my proposed world it would be possible to create a Date subclass that will serialize a date with its timezone tag and revive it always frozen to that timezone. This kind of serialization couldn't be stored directly as a Date in IDB, but that's not much of a limitation. Same goes for JSON, which doesn't even have a native Date so you need a custom cons anyway.

# Dean Landolt (12 years ago)

On Mon, Apr 15, 2013 at 10:01 AM, Dean Landolt <dean at deanlandolt.com> wrote:

Perhaps I wasn't clear: I was proposing the timezone property as purely informative for the locale methods. The Date constructor used to revive the IDB value will dictate the date's timezone, so no, the cloned date wouldn't carry its timezone with it. However, in my proposed world it would be possible to create a Date subclass that will serialize a date with its timezone tag and revive it always frozen to that timezone. This kind of serialization couldn't be stored directly as a Date in IDB, but that's not much of a limitation. Same goes for JSON, which doesn't even have a native Date so you need a custom cons anyway.

To drive this point home perhaps a suitable key would be localeTimezone to communicate that this is the timezone used by the locale-specific methods. It's seems unlikely to conflict with popular libraries, but I could do a quick survey and code search to confirm.

# Norbert Lindenberg (12 years ago)

On Apr 15, 2013, at 5:43 , Dean Landolt wrote:

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg <ecmascript at lindenbergsoftware.com> wrote:

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

No, Date instances are in UTC - read the spec. esdiscuss/2013-March/028928

The time zone of the host system is, as you say, global state. Confusing instance data and global state has real hazards in many areas of software development.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no impact on a date's underlying value, just on the behavior of its locale methods.

So which one are you proposing: having "Date instances ... own their timezone" or "slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol"? These are not the same.

If you want to alter the timezone used for locale methods on a specific instance just set this property.

Changing the property would affect all instances that have Date.prototype as their prototype, not just "a specific instance".

# Dean Landolt (12 years ago)

On Mon, Apr 15, 2013 at 11:46 AM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

On Apr 15, 2013, at 5:43 , Dean Landolt wrote:

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

No, Date instances are in UTC - read the spec. esdiscuss/2013-March/028928

I believe you're misunderstanding me.

The time zone of the host system is, as you say, global state. Confusing instance data and global state has real hazards in many areas of software development.

You're suggesting that implicit, hidden global state is the right thing? Can you think of another example in the language of this kind of ambient state? If there is I bet it'd look like a bug.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no impact on a date's underlying value, just on the behavior of its locale methods.

So which one are you proposing: having "Date instances ... own their timezone" or "slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol"? These are not the same.

As you've said, the underlying "value" of a date is UTC. But there are a bunch of locale-specific methods that depend on a global timezone state. I'm simply suggesting that instead of this global state it would be better if these locale-specific methods resolved the appropriate timezone instead by using an explicit property (using prototypal inheritance for a sane default). Again, this timezone is not part of the "value" of a date, and would not be preserved on copy. It simply codifies something that's already happening, allowing it to be controlled in an idiomatic way.

If you want to alter the timezone used for locale methods on a specific instance just set this property.

Changing the property would affect all instances that have Date.prototype as their prototype, not just "a specific instance".

Sure, if you set the property on Date.prototype, but I didn't say to do that. Perhaps code will clear things up -- here's an example of using my proposal and its effects:

Date.prototype.localeTimezone;
// 'America/New_York'
var d = new Date('2013-04-15Z');
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
+d;
// 1365984000000
d.localeTimezone = 'America/Los_Angeles';
// 'America/Los_Angeles'
d;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)
+d;
// 1365984000000
var e = new Date(d);
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
Date.prototype.localeTimezone = 'America/Los_Angeles';
e;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)

Only locale-specific methods are affected -- we're just making the global lookup for timezone into a prototypal one. I can't imagine anything more idiomatic.

# Norbert Lindenberg (12 years ago)

On Apr 15, 2013, at 9:23 , Dean Landolt wrote:

On Mon, Apr 15, 2013 at 11:46 AM, Norbert Lindenberg <ecmascript at lindenbergsoftware.com> wrote:

On Apr 15, 2013, at 5:43 , Dean Landolt wrote:

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg <ecmascript at lindenbergsoftware.com> wrote:

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

No, Date instances are in UTC - read the spec. esdiscuss/2013-March/028928

I believe you're misunderstanding me.

That's always possible. What did I misunderstand, and what did you really mean?

The time zone of the host system is, as you say, global state. Confusing instance data and global state has real hazards in many areas of software development.

You're suggesting that implicit, hidden global state is the right thing?

I said no such thing. I only said that it's different from instance data.

Can you think of another example in the language of this kind of ambient state? If there is I bet it'd look like a bug.

The other example I'm aware of is the default locale, and we addressed that by adding locales arguments to the locale sensitive functionality in the internationalization API. We similarly addressed the default time zone issue by adding a timeZone property in the options argument of DateTimeFormat and the Date.prototype.toLocale*String methods, and in the latest draft of the internationalization API spec that allows for the complete set of IANA time zone names. In this thread, Nebojša and Sorin proposed to add time zone arguments to other functions. These are all steps towards making the runtime's default time zone irrelevant. Your proposals need to be seen in this context, not just in the old ES5 context of a pervasively used implicit global time zone.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no impact on a date's underlying value, just on the behavior of its locale methods.

So which one are you proposing: having "Date instances ... own their timezone" or "slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol"? These are not the same.

As you've said, the underlying "value" of a date is UTC. But there are a bunch of locale-specific methods that depend on a global timezone state. I'm simply suggesting that instead of this global state it would be better if these locale-specific methods resolved the appropriate timezone instead by using an explicit property (using prototypal inheritance for a sane default). Again, this timezone is not part of the "value" of a date, and would not be preserved on copy. It simply codifies something that's already happening, allowing it to be controlled in an idiomatic way.

Together with the sample code below, this sounds like a third variant: Date instances by default don't own their time zone, but the methods do a property lookup for the time zone on Date instances, which by default gets the property of Date.prototype, but can be overridden by adding the property to the instance directly. Is that what you mean?

Also, when you say "locale-specific methods", do you really mean just the locale dependent methods (toLocaleString, toLocaleTimeString, toLocaleDateString), or do you mean all methods that depend on the local time zone (including the constructor, getTimeZoneOffset, getHour, etc.)?

Now, recording the default time zone as a property of Date.prototype and making some methods depend on it means in typical multi-component web applications that one component can change the default time zone and thus affect the behavior of other components, and may open a communications channel between components that are not supposed to communicate. We discussed similar proposals for the default locale during the development of the internationalization API, but rejected them because of these issues.

If you want to alter the timezone used for locale methods on a specific instance just set this property.

Changing the property would affect all instances that have Date.prototype as their prototype, not just "a specific instance".

Sure, if you set the property on Date.prototype, but I didn't say to do that. Perhaps code will clear things up -- here's an example of using my proposal and its effects:

Date.prototype.localeTimezone;
// 'America/New_York'
var d = new Date('2013-04-15Z');
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
+d;
// 1365984000000
d.localeTimezone = 'America/Los_Angeles';
// 'America/Los_Angeles'
d;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)

Why didn't the hours change here? Midnight UTC should be 17:00:00 in PDT.

+d;
// 1365984000000
var e = new Date(d);
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
Date.prototype.localeTimezone = 'America/Los_Angeles';
e;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)

And here?

# Dean Landolt (12 years ago)

On Mon, Apr 15, 2013 at 2:13 PM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

On Apr 15, 2013, at 9:23 , Dean Landolt wrote:

On Mon, Apr 15, 2013 at 11:46 AM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

On Apr 15, 2013, at 5:43 , Dean Landolt wrote:

On Sun, Apr 14, 2013 at 10:49 PM, Norbert Lindenberg < ecmascript at lindenbergsoftware.com> wrote:

I'm afraid this would be quite confusing. Many people believe already that Date instances are in some local time zone, which they aren't, and this would lead even more astray.

Of course Date instances are in some local timezone -- the timezone of the host system. This data isn't explicitly carried along with each date -- instead it's just more implicit global state. But it's naive and even hazardous to pretend a Date instance has no timezone component -- to say this with a strait face would requiring removing the locale-specific date methods. This is what is leading so many astray. Further, I've found that changing the host timezone can wreak havoc on this implicit state in some environments. I couldn't find anything in the spec about expected behavior but there are subtle but real hazards lurking here.

No, Date instances are in UTC - read the spec. esdiscuss/2013-March/028928

I believe you're misunderstanding me.

That's always possible. What did I misunderstand, and what did you really mean?

I wasn't suggesting Date instances be anything other than UTC. Based on your other responses below I believe that misunderstanding was cleared up. Thanks for bearing with me...

The time zone of the host system is, as you say, global state. Confusing instance data and global state has real hazards in many areas of software development.

You're suggesting that implicit, hidden global state is the right thing?

I said no such thing. I only said that it's different from instance data.

Sorry -- I read it as suggesting the current state of affairs was in some way superior.

Can you think of another example in the language of this kind of ambient state? If there is I bet it'd look like a bug.

The other example I'm aware of is the default locale, and we addressed that by adding locales arguments to the locale sensitive functionality in the internationalization API. We similarly addressed the default time zone issue by adding a timeZone property in the options argument of DateTimeFormat and the Date.prototype.toLocale*String methods, and in the latest draft of the internationalization API spec that allows for the complete set of IANA time zone names. In this thread, Nebojša and Sorin proposed to add time zone arguments to other functions. These are all steps towards making the runtime's default time zone irrelevant. Your proposals need to be seen in this context, not just in the old ES5 context of a pervasively used implicit global time zone.

This is an improvement to be sure, but I don't think I understand how it will have much impact on how pervasively the implicit global time zone is dependent upon. The locale-dependent methods will still be just as prominent and leaned on heavily I'd bet.

But I also don't see how the two approaches are in conflict at all -- to my mind they complement each other nicely. Any timeZone properties in the i18n formatting stuff would take precedence, of course, just as they do today over the implicit global.

Previously I'd suggested that Date instances should just own their timezone. Make explicit what's already there implicitly -- slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol instead of some hidden global state. Of course this has no impact on a date's underlying value, just on the behavior of its locale methods.

So which one are you proposing: having "Date instances ... own their timezone" or "slap the system timezone as a symbol on Date.prototype and correct all locale-specific date methods to respect this symbol"? These are not the same.

As you've said, the underlying "value" of a date is UTC. But there are a bunch of locale-specific methods that depend on a global timezone state. I'm simply suggesting that instead of this global state it would be better if these locale-specific methods resolved the appropriate timezone instead by using an explicit property (using prototypal inheritance for a sane default). Again, this timezone is not part of the "value" of a date, and would not be preserved on copy. It simply codifies something that's already happening, allowing it to be controlled in an idiomatic way.

Together with the sample code below, this sounds like a third variant: Date instances by default don't own their time zone, but the methods do a property lookup for the time zone on Date instances, which by default gets the property of Date.prototype, but can be overridden by adding the property to the instance directly. Is that what you mean?

Perhaps my use of the word "own" was the wrong choice -- what I meant to imply was that locale methods should first look to an "own" key -- I didn't mean to imply this wouldn't fall through prototypally -- just the opposite.

Also, when you say "locale-specific methods", do you really mean just the

locale dependent methods (toLocaleString, toLocaleTimeString, toLocaleDateString), or do you mean all methods that depend on the local time zone (including the constructor, getTimeZoneOffset, getHour, etc.)?

All locale-dependent methods -- I should have made that more clear.

Now, recording the default time zone as a property of Date.prototype and

making some methods depend on it means in typical multi-component web applications that one component can change the default time zone and thus affect the behavior of other components, and may open a communications channel between components that are not supposed to communicate. We discussed similar proposals for the default locale during the development of the internationalization API, but rejected them because of these issues.

Okay, I think we're at least talking about the same thing now. Though a close reading suggests to me there may be a misunderstanding of the fundamental OCap principles at issue here. There would be no channel that isn't already in place -- Date instances are already mutable and extensible. While I agree with the thrust of your point, it could just as easily be said about any of the other built-ins, and much more seriously at that. Any hazard from modifying Date.prototype.localeTimezone (or whatever it's called) would beovershadowed by poorly modifying many of the other built-in prototypes. Fortunately es5 gives us the tools to correct this.

And this is an important point -- I believe explicit (and freezable) state is substantially more friendly for mutually suspicious code than an implicit and underspecified global. I strongly suspect this would be a welcome development for secure programming (MarkM, TomVC or one of the many other OCap experts on this list please correct me if I'm wrong!), since it gives us the opportunity to actually shut down a (potential) communications channel present in the ambient environment.

We can certainly disagree about whether this is the right API but I believe any argument based on POLA will only strengthen my case :)

If you want to alter the timezone used for locale methods on a specific instance just set this property.

Changing the property would affect all instances that have Date.prototype as their prototype, not just "a specific instance".

Sure, if you set the property on Date.prototype, but I didn't say to do that. Perhaps code will clear things up -- here's an example of using my proposal and its effects:

Date.prototype.localeTimezone;
// 'America/New_York'
var d = new Date('2013-04-15Z');
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
+d;
// 1365984000000
d.localeTimezone = 'America/Los_Angeles';
// 'America/Los_Angeles'
d;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)

Why didn't the hours change here? Midnight UTC should be 17:00:00 in PDT.

Sorry -- my mistake.

+d;
// 1365984000000
var e = new Date(d);
// Sun Apr 14 2013 20:00:00 GMT-0400 (EDT)
Date.prototype.localeTimezone = 'America/Los_Angeles';
e;
// Sun Apr 14 2013 20:00:00 GMT-0700 (PDT)

And here?

Copy/paste of the same oversight :)