0

我有这个代码

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

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

谢谢

4

1 回答 1

1

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

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

在此处输入图像描述

查看此页面了解更多信息。

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

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

以下代码演示:

  1. LocalDateTime直到将1893-10-31T23:49转换为DateTime具有49分钟和56秒的偏移量。
  2. 如上所述,LocalDateTimefrom 1893-10-31T23:50to将引发异常。1893-10-31T23:59
  3. LocalDateTime开头的将1893-11-01T00:00转换为小时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 切换到现代日期时间 API*

在Joda-Time 主页查看以下通知:

Joda-Time 是 Java SE 8 之前 Java 的事实上的标准日期和时间库。现在要求用户迁移到 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 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

于 2021-02-28T19:04:17.273 回答