Java将rfc1123日期时间从epoch转换为毫秒



我正在尝试将RFC 1123格式的日期转换为Java中epoch的毫秒数。

我的用例是,我已经上传了一个文件到我的pCloud存储(直接从我的浏览器),然后从java,请求REST API检索这个文件的最后修改日期时间。

我收到的字符串是"Fri, 08 Apr 2022 15:57:48 +000 "

但是从我的电脑,文件最后修改是在17:57:48。但是我在欧洲/巴黎,所以我在时区偏移+2。

I tried to do:

String modified = "Fri, 08 Apr 2022 15:57:48 +0000";
DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME;
LocalDateTime localDateTime = LocalDateTime.parse(modified, formatter);
ZonedDateTime zdt = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());

此时,如果我输出变量:

System.out.println(localDateTime);
System.out.println(zdt);

它显示:

2022-04-08T15:57:48
2022-04-08T15:57:48+02:00[Europe/Paris]

现在从epoch时间转换为毫秒,我试过:

localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
zdt.toInstant().toEpochMilli();
localDateTime.toInstant(OffsetDateTime.now().getOffset()).toEpochMilli();

所有这些给

1649426268000

如果我使用下面的格式器:

new SimpleDateFormat("YYYY/MM/dd HH:mm:ss").format(long milliseconds).

显示:

2022/04/08 15:57:48

所以它错过了我的时区偏移量?("+ 02:00(欧洲/巴黎)")。

我找到了这个解决方案:

TimeZone tz = TimeZone.getTimeZone(ZoneId.systemDefault());
long milli = zdt.toInstant().toEpochMilli() + tz.getOffset(new Date().getTime())

和之前一样使用相同的SimpleDateFormat格式化milli,我有:

2022/04/08 17:57:48

是正确的值。

是否有一个更干净的方式有正确的长毫秒到epoch从我的字符串日期在RFC 1123格式?

特别是我认为在我的解决方案中我必须做一些像

这样的事情
tz.getOffset(extact date from "modified" string)

,因为根据夏令时(夏季或冬季),偏移量是不一样的,我希望这个用例必须与Java的所有类一起本地管理?

您正在使用仅存储日期和时间组件的LocalDateTime。然后继续应用本地时区。您的本地时区与此任务无关,因此不应使用。

相反,由于您的输入包含日期、时间和偏移量,您应该解析为OffsetDateTime

String modified = "Fri, 08 Apr 2022 15:57:48 +0000";
DateTimeFormatter formatter = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse(modified, formatter);

那么您可以使用以下任意一种方式来获取自epoch以来的毫秒数:

odt.toInstant().toEpochMilli()

odt.toEpochSecond() * 1000

将给你正确的1649433468000值。查看IdeOne.com上运行的类似代码。

(注意,在OffsetDateTime上没有直接的toEpochMilli方法,所以要么先通过Instant,要么得到秒并乘以1000。)

最新更新