将字符串日期“2020-10-31T00:00:00Z”转换为long型。

11 浏览
0 Comments

将字符串日期“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日。请有人可以解释这个吗?

0
0 Comments

问题的原因是将字符串日期解析为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的情况如此)。感谢你的改进。

0