【问题标题】:convert from org.joda.time.LocalDateTime to java.sql.date从 org.joda.time.LocalDateTime 转换为 java.sql.date
【发布时间】:2021-05-27 18:40:46
【问题描述】:

我有这个代码

LocalDateTime localDateTime = LocalDateTime.parse("1777-11-11T00:00:00.000");
System.out.println("DateTimeZone.getDefault default" + DateTimeZone.getDefault());
System.out.println("Milliseconds UTC" + localDateTime.toDateTime(DateTimeZone.UTC).getMillis());
System.out.println("Milliseconds Europe rome" + localDateTime.toDateTime(DateTimeZone.forID("Europe/Rome")).getMillis());
java.sql.Timestamp t = new java.sql.Timestamp(localDateTime.toDateTime(DateTimeZone.forID("Europe/Rome")).getMillis());
System.out.println("End Date: "+  new java.sql.Timestamp(localDateTime.toDateTime(DateTimeZone.forID("Europe/Rome")).getMillis()));
        

我将日期从 org.joda.time.LocalDateTime 转换为 java.sql.date

输出是

DateTimeZone.getDefault defaultEurope/Rome
Milliseconds UTC   -6063292800000
Milliseconds Europe rome  -6063295796000
End Date: 1777-11-11 00:10:04.0

所以分钟和秒是错误的。 为什么会这样?我该如何解决?

谢谢

【问题讨论】:

  • 我建议您既不要使用java.sql.Date,也不要使用java.sql.Timestamp。这两个类的设计都很糟糕并且已经过时了。而是使用例如来自java.time, the modern Java date and time APILocalDateLocalDateTime。此外,java.time 已经取代了 Joda-Time,因此对于更简单和现代的代码,请使用 java.time。那么您可能根本不需要任何转换。

标签: java datetime jodatime java-time localdatetime


【解决方案1】:

所以分钟和秒是错误的。为什么会这样?

之所以发生这种情况,是因为在意大利,距离 1893-10-31T23:49 之前的区域偏移量为 49 分钟和 56 秒。

查看this page了解更多信息。

另外,请注意以下关于org.joda.time.LocalDateTime#toDateTime 的事实:

应用时区时,本地日期时间可能会受到以下因素的影响 夏令时。在夏令时间隙,当当地时间 不存在,这个方法会抛出异常。在夏令时 重叠,当同一本地时间出现两次时,此方法返回 本地时间的第一次出现。

以下代码演示:

  1. 直到1893-10-31T23:49LocalDateTime 将转换为DateTime,偏移量为49 分钟和56 秒。
  2. 1893-10-31T23:501893-10-31T23:59LocalDateTime 将抛出上述异常。
  3. 1893-11-01T00:00 开头的LocalDateTime 将转换为DateTime,偏移量为+01:00 小时。

演示:

import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;

public class Main {
    public static void main(String[] args) {
        // Test date-time strings
        String[] arr = { "1893-10-31T23:49:00.000", "1893-11-01T00:00:00.000", "1893-10-31T23:50:00.000" };
        
        for (String dt : arr) {
            LocalDateTime localDateTime = LocalDateTime.parse(dt);
            System.out.println(localDateTime);
            System.out.println(localDateTime.toDateTime(DateTimeZone.forID("Europe/Rome")));
        }
    }
}

输出:

1893-10-31T23:49:00.000
1893-10-31T23:49:00.000+00:49:56
1893-11-01T00:00:00.000
1893-11-01T00:00:00.000+01:00
1893-10-31T23:50:00.000
Exception in thread "main" org.joda.time.IllegalInstantException: Illegal instant due to time zone offset transition (daylight savings time 'gap'): 1893-10-31T23:50:00.000 (Europe/Rome)
    at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:157)
    at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:122)
    at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
    at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:257)
    at org.joda.time.DateTime.<init>(DateTime.java:532)
    at org.joda.time.LocalDateTime.toDateTime(LocalDateTime.java:753)
    at Main.main(Main.java:12)

建议从Joda-Time切换到modern date-time API*

Home Page of Joda-Time查看以下通知:

Joda-Time 是 Java 的事实上的标准日期和时间库 在 Java SE 8 之前。现在要求用户迁移到 java.time (JSR-310)。

使用 java.time API:

import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        // Test date-time strings
        String[] arr = { "1893-10-31T23:49:00.000", "1893-11-01T00:00:00.000", "1893-10-31T23:50:00.000" };
        ZoneId zoneId = ZoneId.of("Europe/Rome");

        for (String dt : arr) {
            LocalDateTime localDateTime = LocalDateTime.parse(dt);
            System.out.println(localDateTime);
            System.out.println(localDateTime.atZone(zoneId));
        }
    }
}

输出:

1893-10-31T23:49
1893-10-31T23:49+00:49:56[Europe/Rome]
1893-11-01T00:00
1893-11-01T00:00+01:00[Europe/Rome]
1893-10-31T23:50
1893-11-01T00:00:04+01:00[Europe/Rome]

Trail: Date Time 了解有关 java.time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2011-08-29
    • 2017-07-13
    • 2013-01-27
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多