[tz] Java & Rearguard

Neil Fuller nfuller at google.com
Fri May 31 15:14:05 UTC 2019


I have the responsibility of updating the time zone data for the Android
Open Source Project for latest code as well as for historic releases of
Android.

The concerns I have fall into categories:

1) Changes of convention that will result in compatibility problems for
users of APIs because of the resulting behavior changes. No easy way for
new code to detect what convention is in use.
2) Bugs that the change in convention reveal that cannot practically be
fixed in the time allowed because of the lifespan of devices, and tz code
and data on devices being updated independently.
3) Simplifications / assumptions / limitations in well-established APIs
that the convention change invalidate.

Losing rearguard / having to adopt negative DST would cause quite a lot of
churn and, FWIW, I'm not in favor.

I haven't posted on this thread until now because I've been trying to
condense my thoughts / explanation down to more digestible nuggets. I've,
unfortunately, completely failed. So, apologies for the length of the
information after my sig; it's really just context for what I said above if
you want to understand why I've said what I have above.

I'm not an official spokesperson for Android / Google, but as a project
that utilizes a lot of open source code and data, and benefits from
volunteer effort, I know I really appreciate all the hard work that goes
into giving our users the best information and behavior possible.

Neil.

-- 
Google UK Limited

Registered Office: 6 Pancras Square, London, N1C 4AG
Registered in England Number: 3977902

-------------------

Detail:

The Android platform is a direct user of zic output (for our own
implementation of the java.util.TimeZone class and libc functions), as well
as integrating ICU4C and ICU4J for localization. Android tooling does not
parse the rules files directly but we don't always use the latest zic
version to do so.

ICU uses an older, modified version of zic when creating its own copy of
time zone binary data. ICU blends in their own additional information like
time zone display names over time, exemplar location translations. Android
exposes numerous time zone APIs for Android apps to use (e.g.
java.util.TimeZone, ICU4J's TimeZone, a modified implementation of
java.time, SimpleDateFormat) and it also uses ICU4J and ICU4C APIs
internally for various functions.

After the first Ireland negative DST switch, I recall I discovered a bug in
Android code associated negative offsets. I don't know / can't remember if
ICU have found any similar issues in their current or older releases. The
Android bugs I know of are fixed in latest Android code but even if I
backport code fixes for older releases I can't be sure manufacturers will
apply them. So, updates to data that I release into AOSP and manufacturers
(or other open source folks like LineageOS) may put into device "roms" will
probably have to continue using rearguard data for safety.

For the platform and for apps, we'd really need the various APIs that
return tz information to be consistent in their approach, which so far has
meant ICU and Android's custom code agreeing on using rearguard data.
Switching universally to vanguard would require coordination to, for
example, avoid APIs with the same contract (e.g. getOffset(long) )
returning positive offsets on one API and negative on another (e.g.
java.util.TimeZone Vs android.icu.util.TimeZone). Differing conventions
could also cause problems for us where we delegate to ICU for string
information, but use the zic data for offset / dst state.

I'm not an expert in the native ICU APIs, but the older Java APIs have
tended to simplify the complex world of time zones and there are decades of
apps written against this simplified model. Apps probably also make
additional assumptions like "DST is always a positive adjustment", "DST is
always in the summer", "!daylight == standard time". This makes the
compatibility story hard if the data we use switches convention when
applying a tzdb data update, especially if the change doesn't take place on
a well-defined Android release boundary. Android applications expect
occasional variations in behavior but we try to make sure that larger
changes tend to take place on Android release boundaries (which apps can
check for) and we often try to limit behavior changes based on an
applications "target API level" (which indicates the release the app was
tested against and is an indicator for the behavior they expect).

As an example of API simplification, methods like
TimeZone.getDisplayName(boolean, int, Locale) [1] take a boolean for
"daylight". Therefore they assume two offsets a year, not many (I believe
this breaks down in some places near the poles). If developers take the
value from the inDaylightTime(Date) method to determine the first parameter
for a given time, and everything is using the same convention, then they'll
probably get their expected behavior regardless of whether it's vanguard of
rearguard data being used. If they wanted "summer" or "winter", to pick the
time to pass to inDaylightTime(), they'd need to know whether a zone was in
the northern or southern hemisphere (not readily available but perhaps
guessable from the first part of the Olson ID but that's not ideal). I
suspect a lot of code just hardcodes "false" and "true" expecting the
rearguard (daylight == summer, !daylight = standard) convention.

Note, also, the method and others like it don't take a parameter for
"when", so tend to assume that the "standard time" convention for
"daylight" and "!daylight" are also consistent for all time for a given
zone.

I'm struggling to come up with a way to preserve API behavior for Android
applications if we switched from rearguard to vanguard as it's a build-time
decision. I think I'm right in saying there's no metadata in the zic output
that would reliably allow code to selectively "reverse out" the convention
change at runtime for affected zones / time periods, hence we would end up
with heuristics like "are any of the dst changes (effectively)
negative?". If we could determine what's going on, perhaps we could
continue to present the old behavior for older apps on newer devices so
they get the behavior they've always expected. I assume if rearguard stops
including negative DST there would be no easily available metadata in the
rules that could be extracted either. Of course, we'd still like rearguard
for older devices, as mentioned above.

Ultimately I see this ending with one of: keeping rearguard as it is
forever, somebody compiling their own metadata, possibly API changes,
and/or a fork occurring. It all seems like a lot of pain.

[1]
https://developer.android.com/reference/android/icu/util/TimeZone.html#getDisplayName(boolean,%20int,%20java.util.Locale)

On Fri, 31 May 2019 at 03:09, Paul Eggert <eggert at cs.ucla.edu> wrote:

> On 5/30/19 2:14 AM, Stephen Colebourne wrote:
> > It is a compatibility requirement of the main Java libraries
> > (including icu4j IIUC) that DST is always positive.
>
> Where is this documented? And what do the main Java libraries do in an
> environment where the DST offset is negative? For example, if I run the
> following shell command on a POSIX-compatible host:
>
> TZ='IST-1GMT0,M10.5.0,M3.5.0/1' java [arguments]
>
> can you give an example of what goes wrong and why? This command gives
> Java the rules that Ireland has used since 1996, with Irish Standard
> Time (1 hour ahead of GMT) used in the summer and GMT (a "negative
> daylight saving time") in the winter.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mm.icann.org/pipermail/tz/attachments/20190531/f7a1de08/attachment-0001.html>


More information about the tz mailing list