当我们从年份为 0001
的 java.util.Date
构造它时,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
除了与时区相关的差异之外,如果您注意到:
Date
对象中的日期为02
,DateTime
中的日期为31
(或00
) code> 如果更改为UTC
)Date
对象中的年份为0001
,DateTime
中的年份为0000
我做错了什么,还是这是一个错误?
做了更多计算
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 天。
最佳答案
不是错误:儒略历与预产期公历
这不是错误。它是有意识地这样设计的。这里有两种不同的日历系统:
- 过时的
java.util.Date
类对 1582 年之前的日期使用儒略历。这是一种反射(reflect)当时欧洲大部分地区实际使用的日历系统的尝试。 - 默认情况下,Joda-Time 和 java.time 都使用 ISO 8601 日历系统(如果您明确指定,也支持其他日历系统)。 ISO 8601 又使用提前公历。推算公历是通过将公历的规则外推到公历发明和引入之前的时代而创建的。因此,它给出的日期与当时实际使用的日期不一致,但反过来又更明确。
对于大多数日期,这两个日历相距几天,当我们接近 1582 年或之后的儒略历与格里高利历交叉时,最多相隔几周,具体取决于司法管辖区。
Joda-Time 支持公历/儒略历
联合公历/儒略历系统 Date
Joda-TIME 也通过 GJChronology
支持使用。类。
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
获取的内容一致.
链接
- ISO8601 Java calendar system在 Joda-Time 网站上。
- Wikipedia article: ISO 8601
- Proleptic Gregorian calendar在维基百科上
- 类似问题:Java: How to get the timestamp of '1000-01-01 00:00:00' in UTC?不同之处在于该问题是关于
ZonedDateTime
来自 java.time,而不是 Joda-Time。
关于java - 这是joda时间的一个错误吗?处理非常旧的(0000 年)即时/负纪元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69558345/