ThreeTen / threeten

This project was the home of code used to develop a modern date and time library for JDK8. Development has moved to OpenJDK and a separate backport project, threetenbp.
http://threeten.github.io/
191 stars 37 forks source link

Tighten definition of Java time-scale #291

Closed jodastephen closed 11 years ago

jodastephen commented 11 years ago

Following some off-list feedback, I'm proposing some slight tightening of the Java time-scale spec:

@@ -148,6 +148,8 @@
  * <li>other times during the day will be broadly in line with the agreed international civil time</li>
  * <li>the day will be divided into exactly 86400 subdivisions, referred to as "seconds"</li>
  * <li>the Java "second" may differ from an SI second</li>
+ * <li>a well-defined algorithm must be specified to map each second in the accurate agreed
+ *  international civil time to each "second" in this time-scale</li>
  * </ul><p>
  * Agreed international civil time is the base time-scale agreed by international convention,
  * which in 2012 is UTC (with leap-seconds).
@@ -155,6 +157,14 @@
  * In 2012, the definition of the Java time-scale is the same as UTC for all days except
  * those where a leap-second occurs. On days where a leap-second does occur, the time-scale
  * effectively eliminates the leap-second, maintaining the fiction of 86400 seconds in the day.
+ * The approved well-defined algorithm to eliminate leap-seconds is specified as
+ * <a href="http://www.cl.cam.ac.uk/~mgk25/time/utc-sls/">UTC-SLS</a>.
+ * <p>
+ * UTC-SLS is a simple algorithm that smoothes the leap-second over the last 1000 seconds of
+ * the day, making each of the last 1000 seconds 1/1000th longer or shorter than an SI second.
+ * Implementations built on an accurate leap-second aware time source should use UTC-SLS.
+ * Use of a different algorithm risks confusion and misinterpretation of instants around a
+ * leap-second and is discouraged.
  * <p>
  * The main benefit of always dividing the day into 86400 subdivisions is that it matches the
  * expectations of most users of the API. The alternative is to force every user to understand
@@ -163,16 +173,10 @@
  * Most applications also do not have a problem with a second being a very small amount longer or
  * shorter than a real SI second during a leap-second.
  * <p>
- * If an application does have access to an accurate clock that reports leap-seconds, then the
- * recommended technique to implement the Java time-scale is to use the UTC-SLS convention.
- * <a href="http://www.cl.cam.ac.uk/~mgk25/time/utc-sls/">UTC-SLS</a> effectively smoothes the
- * leap-second over the last 1000 seconds of the day, making each of the last 1000 "seconds"
- * 1/1000th longer or shorter than a real SI second.
- * <p>
  * One final problem is the definition of the agreed international civil time before the
  * introduction of modern UTC in 1972. This includes the Java epoch of {@code 1970-01-01}.
  * It is intended that instants before 1972 be interpreted based on the solar day divided
- * into 86400 subdivisions.
+ * into 86400 subdivisions, as per the principles of UT1.
  * <p>
  * The Java time-scale is used for all date-time classes.
  * This includes {@code Instant}, {@code LocalDate}, {@code LocalTime}, {@code OffsetDateTime},
RogerRiggs commented 11 years ago

I hope this matures into a full IETF spec, we (JDK) can't refer to some random document that isn't endorsed by a standards body. If necessary, we will need to fully incorporate the defined behavior.

RogerRiggs commented 11 years ago

Also, in earlier discussions, we concluded that JSR 310 itself could not solve the leap-year problem and that the underlying OS was responsible. Are now making java.time responsible for smoothing? Where should it be implemented? Clock?

jodastephen commented 11 years ago

The key phrase is "Implementations built on an accurate leap-second aware time source". Since the JDK is not built on such as source, it does not have to use UTC-SLS. What the change is saying is that if you are built on such a source, you really should use UTC-SLS. I'm also leaving enough of a gap open that should an alternative or variant of UTC-SLS get approved (say at the 2014 UTC conference) then Java can move to it (as it would be a new version of UTC, allowing us to have a new approved conversion algorithm).

So, this is just a words change, only affecting non-Oracle-JDK implementations, and generally not affecting those.

jodastephen commented 11 years ago

Applied in http://hg.openjdk.java.net/threeten/threeten/jdk/rev/ca671c2e333f

(Note that I've pushed this before hearing back from my off-list reviewer, so there may yet be more tweaks, although I hope not)

jodastephen commented 11 years ago

Final proposed text:

The Java time scale divides each calendar day into exactly 86400
subdivisions, known as seconds.  These seconds may differ from the SI
second.  It closely matches the de facto international civil time
scale, the definition of which changes from time to time.

The Java time scale has slightly different definitions for different
segments of the time-line, each based on the consensus international
time scale that is used as the basis for civil time. Whenever the
internationally-agreed time scale is modified or replaced, a new
segment of the Java time scale must be defined for it.  Each segment
must meet these requirements:

 * the Java time scale shall closely match the underlying
international civil time scale;
 * the Java time scale shall exactly match the international civil
time scale at noon each day;
 * the Java time scale shall have a precisely-defined relationship to
the international civil time scale.

There are currently, as of 2013, two segments in the Java time-scale.

For the segment from 1972-11-03 (exact boundary discussed below) until
further notice, the consensus international time scale is UTC (with
leap seconds).  In this segment, the Java time scale is identical to
UTC-SLS [hyperlink]. This is identical to UTC on days that do not have
a leap second. On days that do have a leap second, the leap second is
spread equally over the last 1000 seconds of the day, maintaining the
appearance of exactly 86400 seconds per day.

For the segment prior to 1972-11-03, extending back arbitrarily far,
the consensus international time scale is defined to be UT1, applied
proleptically, which is equivalent to the (mean) solar time on the
prime meridian (Greenwich). In this segment, the Java time scale is
identical to the consensus international time scale. The exact
boundary between the two segments is the instant where UT1 = UTC
between 1972-11-03T00:00 and 1972-11-04T12:00.

Implementations of the Java time-scale using the JSR-310 API are not
required to provide any clock that is sub-second accurate, or that
progresses monotonically or smoothly. Implementations are therefore
not required to actually perform the UTC-SLS slew or to otherwise be
aware of leap seconds. JSR-310 does, however, require that
implementations must document the approach they use when defining a
clock representing the current instant.
RogerRiggs commented 11 years ago

ok.

Where will the JDK implementation document the approach of following the system clock?

jodastephen commented 11 years ago

That needs documenting in Clock, where it currently refers to System.currentTimeMillis()

jodastephen commented 11 years ago

Resolved by http://hg.openjdk.java.net/threeten/threeten/jdk/rev/10b3e4872af6