java - Joda Time : Date Convert Bug

标签 java timezone jodatime

我正在使用 Joda Time 2.3 将字符串转换为 java.lang.Date。

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.3</version>
</dependency>

这是一些测试代码:

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());

它在 JDK 5 和 JDK 7 下运行良好。但是当使用 JDK 6 时,结果是:

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

您看到第一个转换为 java.lang.Date 丢失了 5 秒,但第二个是正确的。唯一不同的是年份,第一个是1927,第二个是1937。凡是1927以下的年份都会报错。​​

这一定是 joda 有问题。有人可以告诉我如何避免这个错误,或者我必须使用 SimpleDateFormatter。

谢谢!

最佳答案

你见过Jon Skeets answer吗?上海时间?我会说,这不是错误,而是时区历史数据中的一个奇怪条目。

请注意,应谨慎处理 tz 历史数据(不是可靠来源,这里只是关于 LMT 的假设 - 中国本地平均时间基于上海经度计算)。 IANA-tzdb 仅在 1970 年之后才产生可靠数据。

编辑:

我已经针对明确的时区“Asia/Shanghai”测试了您的代码(适合您的示例输出中的时区名称 CST)并得到:

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());

输出:

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

与您的结果相比有 5 秒的小差异,因为我们使用了不同版本的时区数据库(+08:05:52 与 +08:05:57 相比,随着 2013a 版的 tzdb 发生了变化 - 另请参阅this commit 在 Paul Eggert 的实验存储库中)。 并且 JDK-version-change 从 5 到 6 或更高版本也可能涉及此更改 - 因此 SimpleDateFormat 的结果相同。就这些。我认为使用 SimpleDateFormat 不会获得更好的结果,请参见此处:

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));

你得到相同的偏移量,即我的 tz 版本 08:05:52 在 java.util.Date.toString()-output 中是不可读的(那里只是给 CST 作为时区名称)。 因此与 JodaTime 相比,偏移量没有差异,前提是 JDK 和 JodaTime 使用相同的 tzdb 版本

关于java - Joda Time : Date Convert Bug,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22680260/

相关文章:

java - 如何在同一个模拟类中 stub 所有方法

java - 我怎样才能从通知转到我的 Viewpager 中添加的最后一个 fragment ?

java - 处理可同步或异步调用的 REST API 路径的正确方法

grails - Grails-在 Controller 中将服务器(UTC日期)转换为用户日期

java - 解析 joda-time

java - hibernate/JPA : foreign key = null

c++ - C/C++ : Why the localtime display incorrectly in respect of its timezone?

scala - joda 时间 ISO 日期时间格式

java - 如何在 Joda Time/Java 8 中列出时区偏移量、时区 ID 和长名称?

javascript - 在 JavaScript 中获取客户端的 GMT 偏移量