这是乔达时间的错误吗?处理非常旧的(0000 年)即时/负纪元

Is this a bug in joda time? Handling very old (year 0000) instant / negative epoch

当我们从 0001.0001.

构造它时,DateTime 似乎没有用正确的日期初始化它自己
import java.time.LocalDateTime;
import java.util.TimeZone;
public class TestMain {
    public static void main(String[] args) {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        java.util.Date d = new java.util.Date(-62135640000000L);
        java.time.Instant i = java.time.Instant.ofEpochMilli(-62135640000000L);
        System.out.println("d = new java.util.Date(-62135640000000L)                      : " + new java.util.Date(-62135640000000L));
        System.out.println("new org.joda.time.DateTime(d)                                 : " + new org.joda.time.DateTime(d));
        System.out.println("new org.joda.time.DateTime(-62135640000000L)                  : " + new org.joda.time.DateTime(-62135640000000L));
        System.out.println("java.time.LocalDateTime.ofInstant(i, java.time.ZoneOffset.UTC): " + LocalDateTime.ofInstant(i, java.time.ZoneOffset.UTC));
    }
}

输出:

d = new java.util.Date(-62135640000000L)                      : Sun Jan 02 12:00:00 UTC 1
new org.joda.time.DateTime(d)                                 : 0000-12-31T12:00:00.000Z
new org.joda.time.DateTime(-62135640000000L)                  : 0000-12-31T12:00:00.000Z
java.time.LocalDateTime.ofInstant(i, java.time.ZoneOffset.UTC): 0000-12-31T12:00

除了与时区相关的差异外,如果您注意到:

我是不是做错了什么,或者这是一个错误?

再计算一下

62135640000000 / 1000 / 3600 / 24 / 365.25 = 1968.9596167008898015058179329227
0.9596167008898015058179329227 * 365.25 = 350.5
365.25 - 350.5 = 14.75

所以-62135640000000 =负1969年350.5天。或 0000 年开始后约 14.75 天。

不是错误:Julian 与 proleptic Gregorian calendar

这不是错误。它是有意识地这样设计的。这里有两种不同的日历系统:

  1. 过时的 java.util.Date class 对 1582 年之前的日期使用儒略历。这是试图反映当时欧洲大部分地区实际使用的日历系统。
  2. Joda-Time 和 java.time 默认情况下都使用 ISO 8601 日历系统(如果您明确指定,则支持其他日历系统)。 ISO 8601 又使用公历。公历是通过将公历规则推回到公历发明和引入之前的时代而创建的。所以它给出的日期与当时实际使用的日期不一致,但反过来,定义更明确。

对于大多数日期,这两个日历相隔几天,当我们接近 1582 年或更晚的儒略-格里高利交叉点时,最多相隔几周,具体取决于司法管辖区。

Joda-Time 支持 Gregorian/Julian 日历

Joda-TIme 也通过 GJChronology class.

支持 Date 使用的组合 Gregorian/Juian 日历系统
    DateTime dt = new DateTime(-62_135_640_000_000L,
            GJChronology.getInstanceUTC());
    System.out.println("DateTime with GJChronology: " + dt);

输出:

DateTime with GJChronology: 0001-01-02T12:00:00.000Z

年、月、日都与您从 Date 中得到的一致。

链接