Reputation: 45
I am using Joda Time 2.3 to convert String to java.lang.Date.
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
Here is some test code:
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime("1927-12-11 11:22:38"));
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime("1927-12-11 11:22:38").toDate());
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime("1937-12-11 11:22:38"));
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime("1937-12-11 11:22:38").toDate());
It works well under JDK 5 and JDK 7. But when using JDK 6, the result is:
1927-12-11T11:22:38.000+08:05:57
Sun Dec 11 11:22:33 CST 1927 // lose 5 second
1937-12-11T11:22:38.000+08:00
Sat Dec 11 11:22:38 CST 1937
You see that the first convert to java.lang.Date lost 5 second, but the second is right. The only difference is the year number, which the first is 1927 and the second is 1937. All the year number below 1927 will cause the wrong.
This must be something wrong about joda. Can somebody tell me how to avoid the bug, or I have to use SimpleDateFormatter.
Thank you!
Upvotes: 4
Views: 461
Reputation: 44071
Have you seen Jon Skeets answer about Shanghai time? I would say, this is not a bug, but a strange entry in time zone history data.
Note, that tz history data should be handled with care (not reliable sources, here just an assumption about LMT - local mean time in China calculated on base of Shanghai longitude). IANA-tzdb yields reliable data only after 1970.
EDIT:
I have tested your code for the explicit time zone "Asia/Shanghai" (fits the time zone name CST in your example output) and get:
DateTimeZone tz = DateTimeZone.forID("Asia/Shanghai");
System.out.println(
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(tz)
.parseDateTime("1927-12-11 11:22:38"));
System.out.println(
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(tz)
.parseDateTime("1927-12-11 11:22:38")
.toDate());
System.out.println(
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(tz)
.parseDateTime("1937-12-11 11:22:38"));
System.out.println(
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(tz)
.parseDateTime("1937-12-11 11:22:38")
.toDate());
Output:
1927-12-11T11:22:38.000+08:05:52
Sun Dec 11 04:16:46 CET 1927 // toString() prints in standard time zone
1937-12-11T11:22:38.000+08:00
Sat Dec 11 04:22:38 CET 1937 // toString() prints in standard time zone
There is a small difference of 5 seconds compared with your results because we use different versions of timezone database (+08:05:52 compared with +08:05:57 changed with version 2013a of tzdb -see also this commit in experimental repository of Paul Eggert). And JDK-version-change from 5 to 6 or later can also involve this change - so the same results with SimpleDateFormat
. That is all. I don't think that you will get better results with SimpleDateFormat
, see here:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setLenient(false);
df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
Date d = df.parse("1927-12-11 11:22:38");
System.out.println(d);
long offset = TimeZone.getTimeZone("Asia/Shanghai").getOffset(d.getTime()) / 1000;
System.out.println(offset);
int offsetHours = (int) (offset / 3600);
long minutes = (offset % 3600);
System.out.println(offsetHours + ":0" + minutes / 60 + ":" + (minutes % 60));
You get the same offset, namely with my tz version 08:05:52 what is not readable in java.util.Date.toString()-output (there just given CST as timezone name). So no difference in offset compared with JodaTime, provided JDK and JodaTime use the same tzdb version.
Upvotes: 5