我的问题是关于在 groovy 中从日期转换纪元毫秒



我使用以下代码生成以毫秒为单位的纪元时间戳,它可以工作(通过 https://www.epochconverter.com/验证)。但是,当我们使用 JVM 选项 -Duser.timezone=America/Toronto 设置时区时,对于某些历史日期,时间偏移量相差一小时。即日期=1950-11-19 (yyyy-MM-dd) 正确的纪元毫秒 -603313200000(1950 年 11 月 19 日星期日上午 12:00:00 GMT-05:00),但当时区设置为 JVM 选项值为 -603316800000 并且大纪元转换显示 1950 年 11 月 18 日星期六晚上 11:00:00 GMT-05:00。我已经在JDK 10中使用了joda time lib

def static Long getEpochTimeStampInMilliSeconds(String simpleDate, String dateFormat) {
Long retVal = null
try {
org.joda.time.format.DateTimeFormatter fmt = DateTimeFormat.forPattern(dateFormat)
DateTimeZone dtz2 = DateTimeZone.forID("America/Toronto")
DateTime parsedDateTime = DateTime.parse(simpleDate, fmt).withZone(dtz2)
retVal = parsedDateTime.getMillis()
} catch (Exception e) {
retVal = null
}
return retVal
}

日期格式为:"yyyy-MM-dd">

您需要使用正确的时区进行解析,因此您需要在使用格式化程序解析之前调用dateTimeFormatter.withZone(...),而不是在解析完成后调用dateTime.withZone(...)

如果由user.timezonesystem 属性设置的默认时区为America/Toronto,则解析的DateTime值已在该时区中,dateTime.withZone(...)将不执行任何操作。

如果默认时区是其他时区,则解析的DateTime值位于该时区,这将是不同的 UTC 纪元毫秒值。调用dateTime.withZone(...)将更改时区,从而更改时间值,但不会更改 UTC 纪元毫秒值。

def dtz2 = org.joda.time.DateTimeZone.forID("America/Toronto")
def fmt = org.joda.time.format.DateTimeFormat.forPattern(dateFormat).withZone(dtz2)
retVal = org.joda.time.DateTime.parse(simpleDate, fmt).getMillis()

更新

来自评论:

对于所有情况,我收到 1950-11-19 的 -603316800000,但正确的值是 -603313200000

让我们使用 Java-Time API 测试哪个值是正确的:

ZoneId zone = ZoneId.of("America/Toronto");
System.out.println(Instant.ofEpochMilli(-603316800000L));
System.out.println(Instant.ofEpochMilli(-603316800000L).atZone(zone));
System.out.println(Instant.ofEpochMilli(-603313200000L));
System.out.println(Instant.ofEpochMilli(-603313200000L).atZone(zone));

输出

1950-11-19T04:00:00Z
1950-11-19T00:00-04:00[America/Toronto]    ⬅ Correct value
1950-11-19T05:00:00Z
1950-11-19T01:00-04:00[America/Toronto]

如您所见,您得到的值 (-603316800000)多伦多时间午夜 1950-11-19 的正确值。

对于多伦多,您会得到偏移量 -04:00,因为在 1950 年,DST 一直持续到 11 月 26 日星期日凌晨 2:00(请参阅 https://www.timeanddate.com/time/zone/canada/toronto),因此东部夏令时间 (EDT) 的偏移量是正确的。

不知道为什么你认为 -603313200000 是正确的值,但事实并非如此。

最新更新