提问人:Bencri 提问时间:8/2/2019 最后编辑:Bencri 更新时间:8/4/2019 访问量:1456
在 java 中转换 1900 年之前的时间戳
Convert a timestamp before year 1900 in java
问:
我的 Android 应用程序与一个 API 通信,该 API 为我提供了以下时间戳:.转换为日期时间,它应该是-2209161600
12-30-1899 00:00:00
问题是,我尝试使用默认库 threetenbp 和 jodatime 转换此时间戳,但我总是使用时区得到相同的错误结果:Europe/Paris
12-30-1899 00:09:21
为什么会这样?
编辑:例如使用jodatime
DateTime dt = new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Paris")); // dt: "1899-12-30T00:09:21.000+00:09:21"
答:
我想我在常见问题解答中找到了答案,作为为什么时区的偏移量与 JDK 不同?
...影响引入新式时区系统之前的日期时间。时区数据是从时区数据库中获取的。该数据库包含有关“当地平均时间”(LMT)的信息,这是在太阳运动后在该地点观察到的当地时间。
Joda-Time 在某个位置选择第一个时区偏移量之前的所有时间都使用 LMT 信息。...
换言之,数据库没有该时间的条目,因此它使用当地平均时间(例如,巴黎为 0:09:21,马德里 1 为 -0:14:44)。
System.out.println(new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Paris")));
System.out.println(new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Madrid")));
将打印
1899-12-30T00:09:21.000+00:09:21
1899-12-29T23:45:16.000-00:14:44
解决方案:取决于需要多少时间,如果 UTC 足够,请使用
new DateTime(-2209161600000L, DateTimeZone.forID("UTC")) // 1899-12-30T00:00:00.000Z
或者只是标准类,如java.time
Instant.ofEpochSecond(-2209161600L)
Instant.ofEpochMilli(-2209161600000L)
1 - http://home.kpn.nl/vanadovv/time/TZworld.html#eur
卡洛斯·休伯格(Carlos Heuberger)可能已经说过了。据我所知,这是使用 UTC 而不是欧洲/巴黎时区的问题。
long unixTimestamp = -2_209_161_600L;
Instant inst = Instant.ofEpochSecond(unixTimestamp);
System.out.println("As Instant: " + inst);
输出为:
即时:1899-12-30T00:00:00Z
如果您需要日期和时间:
OffsetDateTime dateTime = inst.atOffset(ZoneOffset.UTC);
System.out.println("As OffsetDateTime: " + dateTime);
As OffsetDateTime:1899-12-30T00:00Z
我错过了什么吗?
解释
为什么这很重要?因为在 1899 年,巴黎使用了巴黎的当地平均时间,即与 UTC 的偏移量 +00:09:21。因此,欧洲/巴黎时区的正确和预期结果是你得到的结果,12-30-1899 00:09:21。要检查此偏移量:请转到法国法兰西岛巴黎的时区。在时区更改下拉列表中,选择 1850 – 1899。您将看到 +00:09:21 的偏移量在整个时间间隔内有效 if 年(在 1891 年更改时区缩写之前和之后)。
评论
-2209161600
12-30-1899 00:00:00