[tz] Java & Rearguard

Stephen Colebourne scolebourne at joda.org
Sat Jun 1 09:50:55 UTC 2019


On Sat, 1 Jun 2019 at 07:10, Paul Eggert <eggert at cs.ucla.edu> wrote:
> I looked into this and found that on Fedora 30 x86-64, OpenJDK 12.0.1 mishandles
>   not only *negative* DST specified via a POSIX TZ string, it also mishandles
> *positive* DST specified via a POSIX TZ string.

This is pretty much what I expected, that the JDK only really handles
identifiers like Europe/Dublin. I have't see much evidence that Java
developers think the lack of support of the POSIX string is a problem.

> On the other hand, this Java
> works fine with TZ='Europe/Dublin' even though Europe/Dublin has negative DST on
> my platform.

As I've said before, both ways of representing the data (old and new)
provide the same output in terms of the offset in summer or winter. It
would be a major problem if they didn't. Java's time-zone data is
stored within the JDK (tzdb.dat) - the operating system is only used
to look up the identifier (so I don't think TZif file is used).

What differs is the value returned by ZoneRules:

 var zone = ZoneId.of("Europe/Dublin");
 var winter = ZonedDateTime.of(2019,1,1,0,0,0,0,zone);
 var summer = ZonedDateTime.of(2019,7,1,0,0,0,0,zone);

 var isDstWinter = zone.getRules().isDaylightSavings(winter.toInstant())
 // false

 var isDstSummer = zone.getRules().isDaylightSavings(summer.toInstant())
 // true

 var winterOffsetSummer = zone.getRules().getStandardOffset(winter.toInstant())
 // Z (+00:00)

 var standardOffsetSummer =
zone.getRules().getStandardOffset(summer.toInstant())
 // Z (+00:00)

Note that Java uses the term "standard offset", not "standard time" here.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/zone/ZoneRules.html
At no stage does the JDK claim that the "standard offset" is the
legally defined "standard time" of the time-zone. It has always been
interpreted as the "base" offset which is used all the time unless
advanced in DST/summer. It doesn't explicitly claim that the savings
is positive, but it does say

"
public Duration getDaylightSavings(Instant instant)
Gets the amount of daylight savings in use for the specified instant
in this zone.
This provides access to historic information on how the amount of
daylight savings has changed over time. This is the difference between
the standard offset and the actual offset. Typically the amount is
zero during winter and one hour during summer. Time-zones are
second-based, so the nanosecond part of the duration will be zero.
This default implementation calculates the duration from the actual
and standard offsets."
"

(Note that all of the above discusses the newer java.time.* API, not
the older one in java.util.*)

> Although this is just one Java platform, it appears that I may have been
> worrying overmuch about Java and tzdb's rearguard format, in the sense that the
> problem appears to have been fixed on Fedora without modifying the Java
> libraries themselves.

The rearguard format is needed as the input to TZUpdater, the Java
tool that updates the time-zone data in the JDK. It needs rearguard
because it needs to ensure that isDaylightSavings() and
getStandardOffset() return the values consistent with previous
versions of Java.

On Sat, 1 Jun 2019 at 08:16, Paul Eggert <eggert at cs.ucla.edu> wrote:
> Stephen Colebourne wrote:
> > Another alternative would be to express both pieces of information in
> > the data somehow
>
> tzdb does that now, if by "data" one includes both ordinary files like "africa",
> and the ziguard.awk file that transforms these files to either rearguard or
> vanguard format. If one is given the ordinary files and the ziguard.awk file,
> one can automatically translate the ordinary files to rearguard, main, or
> vanguard format. This means that the information you're requesting is already
> present in tzdb, albeit in a somewhat convoluted form. The form is not that bad
> and the alternative (changing the format of the zic input file) would impose
> more-serious conversion headaches.

The purpose of this thread from my perspective is mainly to highlight
that the data we extract from rearguard is going to be needed forever.
Mark Davis and others have indicated similar. I've suggested ways to
get that data formalised that don't need to execute code. Personally,
I think it would be better for the main file to revert to having no
negative SAVE values as I think it will cause you less pain over time
- it would certainly result in far fewer issues for some pretty major
downstream projects.

Stephen



More information about the tz mailing list