Calendar issues

# Norbert Lindenberg (13 years ago)

ES5 section 15.9.1 specifies a number of operations to map time values (measured in milliseconds from January 1, 1970, midnight UTC) to year/month/day/hour/minute/second values, and the ECMAScript Internationalization API specification section 12.3.2 mandates use of these algorithms also for formatting localized date and time strings if the Gregorian calendar is used.

A well-placed test within the SpiderMonkey test suite reminded me of two issues related to that:

  • The algorithms use a proleptic Gregorian calendar, that is, apply the rules of the Gregorian calendar all the way back to the beginning of ECMAScript time. Normal usage, however, is to use the Julian calendar for dates before the introduction of the Gregorian calendar in 1582 (and in some countries for quite some time after that).

  • The year calculation assumes that there was a year 0, while in normal usage the year before 1 AD is 1 BC.

With to the first issue, the November 2011 draft of the spec had limited applicability of the 15.9.1 algorithms to the internationalization API to dates after 1930, but then somebody (I forgot who) convinced me to remove that limitation. I don't think the second issue has ever been discussed, and introducing a year 0 where there was none just seems wrong to me.

Current implementations of Date.prototype.toLocaleString are split: Firefox, Chrome, and Opera format a date in 1 BC as being in the year 0, while Safari formats it as being in the year 1 (means BC but doesn't say so) and Explorer formats it as being in the year 1 BC. Safari calculates the day according to the Julian calendar, all others use the proleptic Gregorian calendar.

Thoughts?

Depending on what we decide, the beginning of ECMAScript time could be anywhere between 271816 BC and 271822 BC...

, Norbert

# Mark Davis ☕ (13 years ago)

Mark plus.google.com/114199149796022210033 * * — Il meglio è l’inimico del bene — **

On Wed, Sep 12, 2012 at 8:43 PM, Norbert Lindenberg < ecmascript at norbertlindenberg.com> wrote:

ES5 section 15.9.1 specifies a number of operations to map time values (measured in milliseconds from January 1, 1970, midnight UTC) to year/month/day/hour/minute/second values, and the ECMAScript Internationalization API specification section 12.3.2 mandates use of these algorithms also for formatting localized date and time strings if the Gregorian calendar is used.

A well-placed test within the SpiderMonkey test suite reminded me of two issues related to that:

  • The algorithms use a proleptic Gregorian calendar, that is, apply the rules of the Gregorian calendar all the way back to the beginning of ECMAScript time. Normal usage, however, is to use the Julian calendar for dates before the introduction of the Gregorian calendar in 1582 (and in some countries for quite some time after that).

The problem is that the date when countries shifted to using Gregorian as the primary calendar varies wildly. And it wasn't just from the Julian calendar; in non-Christian countries, it was from many others (often still in use as a secondary calendar). And historically, there were transitions between those calendars. And not everyone in the same country followed the same calendar, or switched at the same time. And even on the Julian calendar, before 525 AD there wasn't the practice of using AD; you'd have to have the year set to the year of the emperor (and let's not talk about the transitions there...)

Anyway, it typically isn't worth the trouble. It is quite customary to use a proleptic calendar; many if not most standards do it.

  • The year calculation assumes that there was a year 0, while in normal usage the year before 1 AD is 1 BC.

If the implementation supports eras, then you would have 2 AD, 1 AD, 1 BC, 2 BC...

If it uses negative proleptic years, then you'd have 2 AD, 1 AD, 0 AD, -1 AD, -2 AD, ...

I don't know that we want to have such a difference be a gating item....

# Mark Davis ☕ (13 years ago)

+Peter, since he has an interest in these issues.

Mark plus.google.com/114199149796022210033 * * — Il meglio è l’inimico del bene — **

# Andrew Paprocki (13 years ago)

On Thu, Sep 13, 2012 at 12:37 AM, Mark Davis ☕ <mark at macchiato.com> wrote:

Anyway, it typically isn't worth the trouble. It is quite customary to use a proleptic calendar; many if not most standards do it.

Having spent a large amount of time dealing with interfacing a Julian/(British) Gregorian calendar system to ES (complete with missing days in 1752) and other large codebases to ES which have to consume the datetimes, proleptic Gregorian is surely the only sane choice. Calendars are like time zones -- they just change so infrequently that most people don't consider them as such. But it doesn't make sense to try to use the interpretation of calendar(s) in any one country as the reference any more than it does to use EST/EDT as the basis for times instead of UTC. Like it or not, proleptic Gregorian is the closest we have to a "universal" calendar for computers. Even if calendar transitions were not dependent on vantage point, supporting the Julian/Gregorian hybrid slows date code by adding conditionals as opposed to being a simple formula.

and Explorer formats it as being in the year 1 BC. Safari calculates the day according to the Julian calendar, all others use the proleptic Gregorian calendar.

That is very surprising to me. Can anyone comment on why Safari chose that implementation?

# Norbert Lindenberg (13 years ago)

On Sep 13, 2012, at 6:55 , Andrew Paprocki wrote:

and Explorer formats it as being in the year 1 BC. Safari calculates the day according to the Julian calendar, all others use the proleptic Gregorian calendar.

That is very surprising to me. Can anyone comment on why Safari chose that implementation?

Probably because that's the default used for date and time formatting in ICU. ICU can be made to use a proleptic calendar by setting the Gregorian cutover to the beginning of time; I don't see an easy way to make it introduce a year 0.

Norbert

# Mark Davis ☕ (13 years ago)

In ICU, we are using Gregorian eras (AD/BC) as customarily interpreted, and there is no year zero. There isn't a simple way to get non-era years—and that form is mostly interesting to techies, not normal people, which is why we support the era form.

(If someone wanted to do it, you could probably get reasonable results by taking the input date, parsing with a calendar, and if the year < 1, set the year field to 1-year, get the date pattern for the locale, get the number pattern for a negative integer in the locale, insert the prefix/suffix around the year field in the date pattern, and format the Calendar date. That's be a dozen or two lines of code, but would need some extra code for exceptions.)

Mark plus.google.com/114199149796022210033 * * — Il meglio è l’inimico del bene — **

# Norbert Lindenberg (13 years ago)

The output of Date.prototype.toLocaleString and DateTimeFormat.prototype.format is also intended for normal people, not for techies. So why should we introduce a year 0 for them?

Norbert

# Mark Davis ☕ (13 years ago)

I really was not very clear about what I think; sorry for rambling a bit.

Yes, I agree that the best result for Gregorian is to have correct era support, which means there is no year zero: you have 2 AD, 1 AD, 1 BC, 2 BC,...

Mark plus.google.com/114199149796022210033 * * — Il meglio è l’inimico del bene — **

# Norbert Lindenberg (13 years ago)

Sounds like we're converging on a proleptic Gregorian calendar with no year 0. Any objections?

Thanks, Norbert

# Andrew Paprocki (13 years ago)

Well just to be clear, there is no year 0 when referring to the eras BC/AD. ISO8601 explicitly calls for a year 0 which corresponds with 1 BC. So as long as any interaction with ISO8601 preserves that behavior, it sounds good.