2

The proposed JavaScript Temporal date/time API casually mentions “Interpreting years, months, or weeks requires a reference point” (source), but I fail to understand what is meant by this.

More specifically, the following is not possible:

let oneWeek = Temporal.Duration.from({ weeks: 1 });
console.log(`one week is ${oneWeek.total('day')} days`);

It will result in the following error:

RangeError: a starting point is required for balancing calendar units

This can be resolved by bloating my code with a relativeTo parameter to the total() call, as follows:

console.log(`one week is ${oneWeek.total({ unit: 'day', relativeTo: Temporal.Now.plainDateISO() })} days`);

But could anyone elaborate on why this is necessary? As far as I can tell a week has always been and will always be seven days…?

Justin Grant
  • 44,807
  • 15
  • 124
  • 208
Tim Molendijk
  • 1,016
  • 1
  • 10
  • 14

1 Answers1

5

As far as I can tell a week has always been and will always be seven days

Even around a daylight saving time change? You know, those Sundays where you change the clock back or forward by one hour? If you measure a duration from, say, Wednesday to the next Wednesday, then this “one week” could be exactly 7 days long, or 6 days and 23 hours, or 7 days and 1 hour.

See the documentation on Balancing Relative to a Reference Point:

Balancing that includes days, weeks, months, and years is more complicated because those units can be different lengths. In the default ISO calendar, a year can be 365 or 366 days, and a month can be 28, 29, 30, or 31 days. In other calendars, years aren’t always 12 months long and weeks aren’t always 7 days. Finally, in time zones that use Daylight Saving Time (DST) days are not always 24 hours long.

This is also referring to leap years.

There’s also discussion in issue #857:

Specifically, the following time scale unit conversions are contextual (the “conversion boundaries”):

  • year ↔ day (365, 366 days)
  • month ↔ day (28, 29, 30, 31 days)
  • minute ↔ second (59, 60, 61 seconds)

That last one is referring to leap seconds.

And of course, the Temporal API has to account for what happened in September, 1752. Related: Get number of days in a specific month that are in a date range.

The point is that the answer to the question of how long some unit of time is, will change depending on context. This isn’t just about time zones; different calendars have all sorts of anomalies.

Sure, the proleptic Gregorian calendar used in browsers might not be affected by the year 1752, but that requires knowledge about which calendar to use. You supply this information with relativeTo; it’s contained within Temporal.Now.plainDateISO(). Now it’s clear that an ISO week can be used which will always have 7 days. But without this information, it’s impossible to tell exactly, and a general date and time API cannot be sure that an ISO week is what you actually meant.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
  • I see. Thanks. I would still argue that a week has always seven days (unless perhaps we explicitly reference September 1752 or something like that), but I guess this is up for debate then. – Tim Molendijk Nov 22 '22 at 18:48
  • The Gregorian calendar in use in browsers is "proleptic" meaning it is extended backwards indefinitely, so the Julian-Gregorian change date isn't a problem here. – ptomato Nov 22 '22 at 19:47
  • A week always has seven days _in the ISO 8601 calendar_, but not necessarily in other calendars. You supply a calendar with the relativeTo parameter. – ptomato Nov 22 '22 at 19:48
  • 1
    @ptomato I’ve addressed your concerns in an edit, thank you! Yes, the fact that `Temporal.Now.plainDateISO()` contains the calendar to use is a very important detail that I forgot to mention. This should be clear now. – Sebastian Simon Nov 22 '22 at 20:22
  • Thanks for introducing the word _proleptic_ to my vocabulary – Kinglish Nov 23 '22 at 19:37