将字符串日期“2020-10-31T00:00:00Z”转换为long型。
将字符串日期“2020-10-31T00:00:00Z”转换为long型。
我有一个输入日期是"2020-10-31T00:00:00Z"。我想解析这个日期以获取长整型的毫秒数。
注意:转换后的毫秒数应为悉尼时间(即GMT+11)。
FYI,
public static long RegoExpiryDateFormatter(String regoExpiryDate) { long epoch = 0; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(TimeZone.getTimeZone("GMT+11")); Date date; try { date = df.parse(regoExpiryDate); epoch = date.getTime(); } catch (ParseException e) { System.out.println("Exception is:" + e.getMessage()); e.printStackTrace(); } System.out.println("Converted regoExpiryDate Timestamp*************** " + epoch); return epoch; }
输出:1604062800000,使用Epoch Converter得到的日期是2019年10月30日,但是我在输入中传递的是31日。请有人可以解释这个吗?
问题的原因是将字符串日期解析为long类型时,使用了错误的时区。通过调用df.setTimeZone(TimeZone.getTimeZone("GMT+11"));
,将日期格式化器解释为GMT+11时区。然而,字符串本身并不应该在该时区下解释。字符串中的Z
表示的是GMT时区,因此应该使用df.setTimeZone(TimeZone.getTimeZone("GMT"));
来解释。
实际上,该字符串是ISO 8601格式的Instant
(或者如果你愿意,可以称之为“时间点”)。因此,可以使用Instant.parse
来解析字符串,并使用toEpochMilli
获取毫秒数:
System.out.println(Instant.parse("2020-10-31T00:00:00Z").toEpochMilli()); // 输出 1604102400000
警告:如果Java 8的API(如Instant
等)可用,你真的不应该再使用SimpleDateFormat
。即使不可用,你也应该使用NodaTime或类似的库。
Sweeper,如果你允许我,我发现你的许多回答比这个更好。在我看来,我们应该帮助这个提问者解决两个重要的问题:(1)不要在日期格式模式字符串中硬编码Z
;(2)摆脱SimpleDateFormat
。如果你愿意,可以将我在问题下方的评论建议复制到你的回答中。
.V. 看一下编辑后的回答。现在好了吗?老实说,我不知道如何在不硬编码Z
的情况下仍然使用SimpleDateFormat
?
无论是使用现代的DateTimeFormatter
还是过时的SimpleDateFormat
,大写字母X
都会匹配Z
作为偏移量(自Java 7以来,SimpleDateFormat
的情况如此)。感谢你的改进。