Java 为什么转换后的Jackson时间与预期的Unix时间不同?
编辑:问题不在于杰克逊,而在于1920年4月1日泰国的时间调整 com.fasterxml.jackson.databind.ObjectMapper是如何工作的?我认为它使用了Unix时间戳 我尝试使用mapper.writeValueAsString()转换java.util.Date 当我使用mapper.readerFor(Date.class.readValue()将字符串转换回日期时,结果是正确的 然而,当我尝试删除最后3个数字并将相同的字符串放入一些转换器网站时,结果会关闭几分钟和几秒钟 请参阅下面的代码Java 为什么转换后的Jackson时间与预期的Unix时间不同?,java,date,jackson-databind,Java,Date,Jackson Databind,编辑:问题不在于杰克逊,而在于1920年4月1日泰国的时间调整 com.fasterxml.jackson.databind.ObjectMapper是如何工作的?我认为它使用了Unix时间戳 我尝试使用mapper.writeValueAsString()转换java.util.Date 当我使用mapper.readerFor(Date.class.readValue()将字符串转换回日期时,结果是正确的 然而,当我尝试删除最后3个数字并将相同的字符串放入一些转换器网站时,结果会关闭几分钟和
Date wayBack=新的简化格式(“yyyy-MM-dd”)。解析(“1900-01-31”);
System.out.println(回程);//星期三1900年1月31日00:00:00
ObjectMapper mapper=新的ObjectMapper();
System.out.println(mapper.writeValueAsString(wayBack));//-2206420924000
反序列化日期=mapper.reader for(Date.class).readValue(mapper.writeValueAsString(wayBack));
System.out.println(反序列化);//星期三1900年1月31日00:00:00
下面是一个来自
请注意,由于我的时区,预计7小时休息,但我不理解17:56分钟的不同。编辑-以下是我试图提供比第一个更好的答案的尝试
背景
在阅读问题中的代码之前,请先做一些背景说明:
1900年1月31日午夜曼谷的历元值(秒)为-2206420924:
LocalDateTime localDateTime = LocalDateTime.parse("1900-01-31T00:00:00");
ZoneId z = ZoneId.of("Asia/Bangkok");
ZonedDateTime ict_1 = ZonedDateTime.of(localDateTime, z);
System.out.println("Epoch seconds: " + ict_1.toEpochSecond());
System.out.println("ICT datetime : " + ict_1);
上面打印的是:
Epoch seconds: -2206420924
ICT datetime : 1900-01-31T00:00+06:42:04[Asia/Bangkok]
Epoch seconds: -2206396800
UTC datetime : 1900-01-31T00:00Z
同一日期UTC午夜的历元值(秒)为-1570060800:
ZonedDateTime utcDateTime = ZonedDateTime.parse("1900-01-31T00:00:00Z");
System.out.println("Epoch seconds: " + utcDateTime.toEpochSecond());
System.out.println("UTC datetime : " + utcDateTime);
上面打印的是:
Epoch seconds: -2206420924
ICT datetime : 1900-01-31T00:00+06:42:04[Asia/Bangkok]
Epoch seconds: -2206396800
UTC datetime : 1900-01-31T00:00Z
1900年1月31日曼谷的午夜时间比英国格林威治的午夜时间(本初子午线或UTC)晚24124秒
这就是说,在那一天,曼谷比UTC时间提前了6小时42分4秒(我相信当时称之为GMT,因为当时还没有建立UTC)
问题中的具体代码
首先,我更改了默认时区以匹配问题中使用的时区:
System.setProperty("user.timezone", "Asia/Bangkok");
问题的下一行有以下作用:
(1) SimpleDataFormat
构造函数使用默认区域设置,其中日期格式字符串未指定区域设置
(2) 然后,parse()
方法创建日期对象:
Date wayBack = new SimpleDateFormat("yyyy-MM-dd").parse("1900-01-31");
System.out.println(wayBack);
System.out.println(wayBack.getTime());
此时,我们可以检查date对象:
Date wayBack = new SimpleDateFormat("yyyy-MM-dd").parse("1900-01-31");
System.out.println(wayBack);
System.out.println(wayBack.getTime());
这将打印以下内容:
Wed Jan 31 00:00:00 ICT 1900
-2206420924000 // epoch milliseconds
这与我们前面在背景部分看到的内容相匹配
当您使用问题中提到的在线工具时,您将看到上述毫秒值报告为以下GMT(UTC)日期时间:
GMT: Tuesday, January 30, 1900 5:17:56 PM
对于上面的输出,我使用了
同样,这也是我们所期待的——当曼谷午夜时分,英国格林威治仍然是前一天的下午
代码的其余部分(包括Jackson对象映射器转换)都受Date
对象的初始设置的约束
对于问题:“com.fasterxml.jackson.databind.ObjectMapper如何工作?我认为它使用了Unix时间戳。”它显示了与核心Java日期对象相同的行为。我相信你的假设是正确的
关于不寻常的补偿
关于上文所示的+06:42:04
的ICT偏移:
1920年4月1日,对当地ICT(印度支那时间)进行了调整,使其与UTC时间一致(如您所述,偏移量为+7小时)。本地时钟向前拨17分56秒,将UTC(GMT)偏移量四舍五入为7小时
有关17分钟和56秒更改的具体参考,请参阅
这就是为什么从1920年4月起,你不会看到这种不寻常的偏移
更多链接
请参阅有关更新的java.time
类的信息,这些类应该用来代替java.util.Date
有关历史时区调整主题的相关深入研究,请参见本页。编辑-以下是我试图提供比第一个更好的答案的尝试
背景
在阅读问题中的代码之前,请先做一些背景说明:
1900年1月31日午夜曼谷的历元值(秒)为-2206420924:
LocalDateTime localDateTime = LocalDateTime.parse("1900-01-31T00:00:00");
ZoneId z = ZoneId.of("Asia/Bangkok");
ZonedDateTime ict_1 = ZonedDateTime.of(localDateTime, z);
System.out.println("Epoch seconds: " + ict_1.toEpochSecond());
System.out.println("ICT datetime : " + ict_1);
上面打印的是:
Epoch seconds: -2206420924
ICT datetime : 1900-01-31T00:00+06:42:04[Asia/Bangkok]
Epoch seconds: -2206396800
UTC datetime : 1900-01-31T00:00Z
同一日期UTC午夜的历元值(秒)为-1570060800:
ZonedDateTime utcDateTime = ZonedDateTime.parse("1900-01-31T00:00:00Z");
System.out.println("Epoch seconds: " + utcDateTime.toEpochSecond());
System.out.println("UTC datetime : " + utcDateTime);
上面打印的是:
Epoch seconds: -2206420924
ICT datetime : 1900-01-31T00:00+06:42:04[Asia/Bangkok]
Epoch seconds: -2206396800
UTC datetime : 1900-01-31T00:00Z
1900年1月31日曼谷的午夜时间比英国格林威治的午夜时间(本初子午线或UTC)晚24124秒
这就是说,在那一天,曼谷比UTC时间提前了6小时42分4秒(我相信当时称之为GMT,因为当时还没有建立UTC)
问题中的具体代码
首先,我更改了默认时区以匹配问题中使用的时区:
System.setProperty("user.timezone", "Asia/Bangkok");
问题的下一行有以下作用:
(1) SimpleDataFormat
构造函数使用默认区域设置,其中日期格式字符串未指定区域设置
(2) 然后,parse()
方法创建日期对象:
Date wayBack = new SimpleDateFormat("yyyy-MM-dd").parse("1900-01-31");
System.out.println(wayBack);
System.out.println(wayBack.getTime());
此时,我们可以检查date对象:
Date wayBack = new SimpleDateFormat("yyyy-MM-dd").parse("1900-01-31");
System.out.println(wayBack);
System.out.println(wayBack.getTime());
这将打印以下内容:
Wed Jan 31 00:00:00 ICT 1900
-2206420924000 // epoch milliseconds
这与我们前面在背景部分看到的内容相匹配
当您使用问题中提到的在线工具时,您将看到上述毫秒值报告为以下GMT(UTC)日期时间:
GMT: Tuesday, January 30, 1900 5:17:56 PM
对于上面的输出,我使用了
同样,这也是我们所期待的——当曼谷午夜时分,英国格林威治仍然是前一天的下午
代码的其余部分(包括Jackson对象映射器转换)都受