Java SystemV timezones and JodaTime - java

I am working with timezones in a Java application using JodaTime. I encounter a problem when trying to build a DateTimeZone (JodaTime) object from the id of a java timezone. Joda throws a
java.lang.IllegalArgumentException: The datetime zone id 'SystemV/HST10' is not recognised
for the folowing list of timezones:
SystemV/HST10
SystemV/YST9
SystemV/YST9YDT
SystemV/PST8
SystemV/PST8PDT
SystemV/MST7
SystemV/MST7MDT
SystemV/CST6
SystemV/CST6CDT
SystemV/EST5
SystemV/EST5EDT
SystemV/AST4
SystemV/AST4ADT
What are these timezones used for? Are they relevant to non-programmers? Should an application designed for general uses support these timezones?
Thanks.

The SystemV time-zone IDs are old and deprecated. However, you can make Joda-Time understand them by re-compiling the joda-time jar file with the systemv time-zone data file included. See the commented out lines in the systemv data file. (ie. uncomment the lines and rebuild the jar file).

I'll add this as a new post, as it provides the answers to my question. SystemV timezones were used in an old UNIX OS, that was named, you guessed it, UNIX SYSTEM V. After discussing with my team, we decided that they are of no importance to non-programers and even to programmers nowadays. So we decided not to use them in our application.
Some references about the SystemV timezones:
http://en.wikipedia.org/wiki/IANA_time_zone_database#Files_in_tzdata
http://en.wikipedia.org/wiki/System_V

You can simply convert java TimeZone to DateTimeZone, using method DateTimeZone#forTimeZone
TimeZone tz = //...
DateTimeZone dtz = DateTimeZone.forTimeZone(tz);
Some of this zones can be parsed without "SystemV/"
So you can use
String tzId = "SystemV/MST7MDT";
DateTimeZone tz = DateTimeZone.forID(tzId.replaceAll("SystemV/", ""));
Also you can make next
TimeZone tz = TimeZone.getTimeZone("SystemV/MST7MDT");
DateTimeZone jodaTz = DateTimeZone.forTimeZone(tz);

Related

Different UTC offset for a date&time and its negative counterpart

On my local configuration (Eclipse 4.11 (2019.03), java runtime 1.8.0, SDK 1.8.0), when converting a local date & time (provided through separate strings) to a CET ZonedDateTime (using an intermediary LocalDateTime built from those strings), I get the following outputs :
input : "2001-10-26" and "21:32:52" => output : 2001-10-26T21:32:52+02:00[CET]
input : "-2001-10-26" and "21:32:52" => output :-2001-10-26T21:32:52+01:00[CET]
So, we see that the UTC offset is not the same.
Of course, we refer to a moment in time where "UTC" and "UTC offset" had not yet been defined...
However, I guess that java designers have implemented some rules for those cases as java process them anyway.
Could someone give me some enlighten about this ?
I have already seen this interesting post Java 8 - tz database time zones but it stays rather vague.
Thanks for helping me with this !
The timezone rules are provided through the abstract ZoneRulesProvider class. The docs mention the default implementation in the ZoneRulesProvider's class description.
The Java virtual machine has a default provider that provides zone rules for the time-zones defined by IANA Time Zone Database (TZDB)
So all rules are originating from the time zone database maintained by IANA, and a copy of it is shipped with the JVM.
For all timezones, the tz database has rules defined, the transitions of when the time on the clock has changed or will change. This way, one could determine what date and time it was or will be on an arbitrary moment on the timeline.
So on 26 October −20011, the UTC offset was apparently +01:00.
I have to add two things. First, I would believe the data from the tzdb, because its maintainers probably have a better understanding of how timezones and their rules work. Second, as Joachim already mentioned in the comments, timezones are a concept that was invented a century ago, so combining timezoned with years like −2001 makes a little sense.
1 Note that the calendar used by most of the people in the world is the Gregorian calendar. In the year −2001, that calendar wasn't invented yet. The java.time package uses the proleptic Gregorian calendar.

For Some Timezones, Corrected Time after setting TimeZone via JodaTime and java.time are giving different results, Why?

Following is a small code snippet in java trying to convert a time in millis to a readable date time format,
Long timeInMillis=1615806808301l; //2021-03-15T16:43:28.301+05:30 IST
String timeZone="Europe/Istanbul";
MutableDateTime mdateTime = new MutableDateTime(timeInMills);
mdateTime.setZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone(timeZone)));
ZonedDateTime zdt = ZonedDateTime.ofInstant(Instant.ofEpochMilli(timeInMills), ZoneId.of(timeZone));
Following are the results given by the Joda[mdateTime] and Java.time[zdt] for the same timeInmillis and timezone,
Europe/Istanbul
2021-03-15T13:13:28.301+02:00[Europe/Istanbul]
2021-03-15T14:13:28.301+03:00[Europe/Istanbul]
Turkey
2021-03-15T13:13:28.301+02:00
2021-03-15T14:13:28.301+03:00[Turkey]
Europe/Moscow
2021-03-15T15:13:28.301+04:00
2021-03-15T14:13:28.301+03:00[Europe/Moscow]
Europe/Minsk
2021-03-15T14:13:28.301+03:00
2021-03-15T14:13:28.301+03:00[Europe/Minsk]
As you can see, For Some Timezones, the results are different,
PS: My actual Intention is not to convert the timeInmillis to a readable date time format, but to understand why the results are different.
PS: The System Timezone was IST[+05:30]
Based on the results you are showing for Joda-Time, you likely are using a very old version.
Time zones change at the whim of governments. It's very important to always use the latest version and to stay on top of updates.
Upgrade to the current version of Joda-Time (2.10.10 at the time of writing this) and the discrepancy you reported should go away.

how to deal with international time?

i build a new website.but the host is in USA.i am not in USA.
i need get the time on the website page to compare with one local Variable.
But because of time difference,it has 8 hous difference。how to solve this problom?
my code
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
java.util.Date currentTime = new java.util.Date();
String dateString = formatter.format(currentTime); `
how to revise these code ?
java.util.Date does not support timezones. You should pass the TimeZone to the formatter instead, by calling formatter.setTimeZone(tz).
joda-time is considered a better choice when working with dates. Note that for the sake of formatting it is fine to use Date, but it is a general advise not to rely on it when it comes to i18n. (Note the many deprecated methods there)
Then make each user set his timezone. Ideally suggest / assume the timezone based on his browser locale. See here
And always store the dates in a fixed timezone - preferably GMT/UTC.
In order to handle timezones, Java includes the Olson timezone database. Find the city in the database that is in the same time zone as you are.
First, you need to get a TimeZone object for the timezone you want. Then, get a Calendar object with the current date and time (or the date and time you wish to use). You can format that with a SimpleDateFormat object.
TimeZone local = TimeZone.getTimeZone("Asia/Tokyo");
Calendar now = Calendar.getInstance(local); // gets time in the current timezone
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
formatter.setTimeZone(local)
String dateString = formatter.format(now.getTime());
Though if you're doing a lot of time manipulation, like Bozho says, go for joda-time. The Java date/time system is confusing and rather poorly designed.
In such cases I always change timezone in Linux:
mv /etc/localtime /etc/localtime-backup
ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
It also can be helpful for reading log files for example (I always see my local time instead of calculating it each time when I need to dig into them)
I think you need to use a Calendar (they are more useful generally than just Date objects). If you create a Calendar, initialised with your locale and timezone, you can do calendar.setDate() using the date you created. If you create another Calendar object with the fields that were entered, you can then do comparisons between the two Calendar objects.

Is there a DateFormatProvider that will use Windows localization information?

I'm writing a java gui application that has to display dates.
Since this application is primarily going to run on Windows systems, I would like to be able to use date & time formats that correspond to the Windows localization settings.
I found DateFormatProvider class, in Java 6, which gave me high hopes ... but I haven't found an implementation that will use the Windows localization information.
Any suggestions?
You should be able to use the DateFormatProvider methods with the default locale returned by getDefault().
The Java Virtual Machine sets the
default locale during startup based on
the host environment.
EDIT: if you can't just pass the default locale to the DateFormat class, there is example code here for implementation of a concrete class that extends DateFormatProvider.
I haven't heard about any Java date formatter that uses MS Windows formatting routines (or just definitions for that matter). Since Java is meant to be multiplatform (compile once, run anywhere), it simply couldn't use underlying OS behavior, for consistency reasons.
You can use DateFormat class as defined here:
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
String formattedDate = dateFormatter(new Date());
One important issue about this class: LONG date formats are broken for Czech, Polish and Russian, possibly for other Slavic languages too. I recommend using MEDIUM date format instead.
BTW. This will format dates for Gregorian or Julian calendars. It won't give you Arabic nor Hebrew calendars (although former is default for some countries).
Edit
I am not aware of your specific requirements, but since you mentioned Locale, maybe ICU4J's DateFormat class is what you looking for. Still, as per my knowledge (which might be incomplete here), they are using their own formatter and localized text database. However, this database is probably more complete (especially on Mac) than the one bundled with JDK (previous ICU snapshot).

SimpleDateFormat give inconsistent results

I am trying to parse a date and I am getting different results when I run the code locally/BST compare to a server in Paris/CEST.
I've reproduced the issue in a the following sample. This is trying to parse the start date for the Australian Grand Prix.
TimeZone tz = TimeZone.getTimeZone("AET");
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH mm");
dateFormat.setTimeZone(tz);
long time = dateFormat.parse("28/03/2010 17 00").getTime();
System.out.println("Time "+time);
It seems like I am setting the timezone correctly on the date format and the current timezone shouldn't be affecting the code. But locally it prints 1269756000000 and in Paris 1269759600000. Any idea?
Answer:
It seems like I was testing with an edge case: the Timezone definition is different on my mac compare to the linux server. If I change the timezone to be: "America/Los_Angeles" I am getting a consistent result. The linux box giving me the wrong result is running java 1.6.0-b105 which might be outdated. I'll try an upgrade
Interesting. According to the TimeZone documentation:
Three-letter time zone IDs For
compatibility with JDK 1.1.x, some
other three-letter time zone IDs (such
as "PST", "CTT", "AST") are also
supported. However, their use is
deprecated because the same
abbreviation is often used for
multiple time zones (for example,
"CST" could be U.S. "Central Standard
Time" and "China Standard Time"), and
the Java platform can then only
recognize one of them.
It would be interesting to see the results if you use "Australia/Melbourne" instead of "AET", but just from a quick experiment that I did, it doesn't seem like it makes a difference.
It's curious that the results are an hour apart, like Daylight Savings Time isn't being taken into account in one of the cases. Stupid question; if you're running on two separate computers, are you sure the times are set correctly on each?
On my system here, the result is "1269756000000" (like on your local system). I would try to check the server in Paris, especially the settings that concern the timezone:
System.out.println(System.getProperty("user.timezone"));
System.out.println(System.getProperty("user.country"));
Maybe this brings up some differences that helps you to solve this issue.

Categories

Resources