Problem with some timezone data from 2023 w/ Java SimpleTimeZone
Hi! [I hope this is the right place to report this problem. I reported it on OpenSUSE bugzilla, but was asked to report it upstrem, too. See https://bugzilla.opensuse.org/show_bug.cgi?id=1213470 for my original bugreport] A few days ago I found that with the 2023c timezone database as installed on OpenSUSE LEAP or RedHat Fedora there are two timezones which produce an IllegalArgumentException in the SimpleTimeZone Java class (from OpenJDK 17): "Asia/Gaza" and "Asia/Hebron" The following small Java programm demonstrates the problem: andreas@localhost:~> cat TimeZoneTest.java import java.util.TimeZone; public class TimeZoneTest { public static void main(String[] argv) { for (final String id : TimeZone.getAvailableIDs()) try { TimeZone.getTimeZone(id).toString(); } catch (Exception ex) { System.out.println("TimeZone " + id + " failed: " + ex); } } } Running this programm with a current Java timezone database installed gives the following output: andreas@localhost:~> java TimeZoneTest.java TimeZone Asia/Gaza failed: java.lang.IllegalArgumentException: Illegal daylight saving value: 0 TimeZone Asia/Hebron failed: java.lang.IllegalArgumentException: Illegal daylight saving value: 0 andreas@localhost:~> rpm -q timezone-java timezone-java-2023c-150000.75.23.1.noarch andreas@localhost:~> java -version openjdk version "17.0.7" 2023-04-18 OpenJDK Runtime Environment (build 17.0.7+0-suse-150400.3.24.1-x8664) OpenJDK 64-Bit Server VM (build 17.0.7+0-suse-150400.3.24.1-x8664, mixed mode, sharing) This is with OpenSUSE LEAP 15.4 and 15.5 I also see the same exceptions with Fedora 37, which also uses a separate 2023c timezone database for Java. Debian based systems (like Debian 11, Debian 12 or Ubuntu 22) run the above program without error. They use the internal tzdb which comes with OpenJDK. It looks like the timezone database contains a 0 for the dstSavings property. The constructor for the SimpleTimeZone Java class wants this calue to be > 0 and throws an IllegalArgumentException if it isn't: public SimpleTimeZone(int rawOffset, String ID, int startMonth, int startDay, int startDayOfWeek, int startTime, int startTimeMode, int endMonth, int endDay, int endDayOfWeek, int endTime, int endTimeMode, int dstSavings) { setID(ID); this.rawOffset = rawOffset; this.startMonth = startMonth; this.startDay = startDay; this.startDayOfWeek = startDayOfWeek; this.startTime = startTime; this.startTimeMode = startTimeMode; this.endMonth = endMonth; this.endDay = endDay; this.endDayOfWeek = endDayOfWeek; this.endTime = endTime; this.endTimeMode = endTimeMode; this.dstSavings = dstSavings; // this.useDaylight is set by decodeRules decodeRules(); if (dstSavings <= 0) { throw new IllegalArgumentException("Illegal daylight saving value: " + dstSavings); } } So: is this a problem with the timezone database or rather a problem with the implementation of the Java SimpleTimeZone class? Thanks! - andreas -- Andreas Haumer *x Software + Systeme | mailto:andreas@xss.co.at Karmarschgasse 51/2/20 | https://www.xss.co.at/ A-1100 Vienna, Austria | Tel: +43-1-6060114-0
On 2023-07-19 06:47, Andreas Haumer via tz wrote:
Hi!
[I hope this is the right place to report this problem. I reported it on OpenSUSE bugzilla, but was asked to report it upstrem, too. See https://bugzilla.opensuse.org/show_bug.cgi?id=1213470 for my original bugreport]
A few days ago I found that with the 2023c timezone database as installed on OpenSUSE LEAP or RedHat Fedora there are two timezones which produce an IllegalArgumentException in the SimpleTimeZone Java class (from OpenJDK 17): "Asia/Gaza" and "Asia/Hebron"
The following small Java programm demonstrates the problem:
andreas@localhost:~> cat TimeZoneTest.java import java.util.TimeZone;
public class TimeZoneTest { public static void main(String[] argv) { for (final String id : TimeZone.getAvailableIDs()) try { TimeZone.getTimeZone(id).toString(); } catch (Exception ex) { System.out.println("TimeZone " + id + " failed: " + ex); } } }
Running this programm with a current Java timezone database installed gives the following output:
andreas@localhost:~> java TimeZoneTest.java TimeZone Asia/Gaza failed: java.lang.IllegalArgumentException: Illegal daylight saving value: 0 TimeZone Asia/Hebron failed: java.lang.IllegalArgumentException: Illegal daylight saving value: 0
andreas@localhost:~> rpm -q timezone-java timezone-java-2023c-150000.75.23.1.noarch
andreas@localhost:~> java -version openjdk version "17.0.7" 2023-04-18 OpenJDK Runtime Environment (build 17.0.7+0-suse-150400.3.24.1-x8664) OpenJDK 64-Bit Server VM (build 17.0.7+0-suse-150400.3.24.1-x8664, mixed mode, sharing)
This is with OpenSUSE LEAP 15.4 and 15.5 I also see the same exceptions with Fedora 37, which also uses a separate 2023c timezone database for Java.
Debian based systems (like Debian 11, Debian 12 or Ubuntu 22) run the above program without error. They use the internal tzdb which comes with OpenJDK.
It looks like the timezone database contains a 0 for the dstSavings property. The constructor for the SimpleTimeZone Java class wants this calue to be > 0 and throws an IllegalArgumentException if it isn't:
public SimpleTimeZone(int rawOffset, String ID, int startMonth, int startDay, int startDayOfWeek, int startTime, int startTimeMode, int endMonth, int endDay, int endDayOfWeek, int endTime, int endTimeMode, int dstSavings) {
setID(ID); this.rawOffset = rawOffset; this.startMonth = startMonth; this.startDay = startDay; this.startDayOfWeek = startDayOfWeek; this.startTime = startTime; this.startTimeMode = startTimeMode; this.endMonth = endMonth; this.endDay = endDay; this.endDayOfWeek = endDayOfWeek; this.endTime = endTime; this.endTimeMode = endTimeMode; this.dstSavings = dstSavings;
// this.useDaylight is set by decodeRules decodeRules(); if (dstSavings <= 0) { throw new IllegalArgumentException("Illegal daylight saving value: " + dstSavings); } }
So: is this a problem with the timezone database or rather a problem with the implementation of the Java SimpleTimeZone class?
As you say the Debian builds use whatever comes with the OpenJDK package, but the RPM spec builds may not use the OpenJDK Java tzdb compiler(s) correctly, not include all the required data, not parse the input properly, or generate the correct output: # Java 6/7 data java -jar %{_javadir}/javazic.jar -V %{version} \ -d javazi \ africa antarctica asia australasia europe northamerica \ southamerica backward etcetera \ %{_datadir}/javazic/tzdata_jdk/gmt \ %{_datadir}/javazic/tzdata_jdk/jdk11_backward # Java 8/9 data java -jar %{_javadir}/tzdb.jar \ -srcdir . -dstfile javazi/tzdb.dat \ africa antarctica asia australasia europe northamerica \ southamerica backward etcetera \ %{_datadir}/tzdb/tzdata_jdk/gmt \ %{_datadir}/tzdb/tzdata_jdk/jdk11_backward Maintainers from Fedora and OpenSuSE need to look at what they are doing different from OpenJDK and/or Debian. -- Take care. Thanks, Brian Inglis Calgary, Alberta, Canada La perfection est atteinte Perfection is achieved non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add mais lorsqu'il n'y a plus rien à retirer but when there is no more to cut -- Antoine de Saint-Exupéry
On 2023-07-19 05:47, Andreas Haumer via tz wrote:
See https://bugzilla.opensuse.org/show_bug.cgi?id=1213470 for my original bugreport]... So: is this a problem with the timezone database or rather a problem > with the implementation of the Java SimpleTimeZone class? It's not clear whether the bug is in the program that generates tzdb.dat (in Fedora 38, the program that generates /usr/share/javazi-1.8/tzdb.dat), or in the Java library that reads tzdb.dat. I doubt whether it's a problem in tzdb itself. That is, it's somewhere in the Java code downstream.
I suspect the Java code is having trouble with Palestine's rule changes as first published in tzdb 2023a. Here are the lines that are probably causing problems: Rule Palestine 2058 max - Mar Sat<=30 2:00 1:00 S Rule Palestine 2075 max - Oct Sat<=30 2:00 0 - These lines are a rough guess as to how Palestine's current DST rules would extend into the indefinite future. They cause zic to generate a TZif file (in Fedora 38, /usr/share/zoneinfo/Asia/Gaza) that ends with the following TZ string: EET-2EEST,M3.4.4/50,M10.4.4/50 The two "50"s in this string rely on an extension to the POSIX.1-2017 TZ string format that has been supported and documented in tzdb since release 2013e, is standardized in Internet RFC 8536 (2019), and is in the POSIX.1-202x draft 3. My guess is that the Java code you're using is older and/or doesn't support this extension. If I'm right, a simple workaround would be to remove the above two lines when generating tzdb.dat. Although this would cause timestamps to be more likely wrong starting in the year 2058, these timestamps are guesswork anyway. If you make that change, please add a comment saying what you're doing, and change the version number of the database to something like 2023c-suse1 so that people know you've made a change. Better, of course, would be for downstream to fix whatever Java code is going awry. Quite possibly it's already fixed and you just need to upgrade to the most recent version of the Java code.
participants (3)
-
Andreas Haumer -
Brian Inglis -
Paul Eggert