java 为什么Instant.now()的格式有时会不同?

sg3maiej  于 2023-02-02  发布在  Java
关注(0)|答案(4)|浏览(180)

我有这样的代码:

String PROPER_DATE_FORMAT = "yyyy-MM-dd";
String format = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(Instant.now().toString());
SimpleDateFormat properFormat = new SimpleDateFormat(PROPER_DATE_FORMAT);
String formatterDate = properFormat.format(d);

现在,大多数时候,这段代码都能工作,但偶尔,我会Instant.now()返回2018-05-25T18:56:09Z,然后它会抛出一个异常,因为格式不匹配。
为什么有时候会不一致?
例外情况是java.lang.RuntimeException: java.text.ParseException: Unparseable date: "2018-05-25T18:56:09Z"
通常情况下,当Instant.now().toString()返回一个具有上述格式的字符串时,同样,这段代码在大多数情况下都有效,但也有几次不起作用,我很困惑为什么。
我想这是否是因为末尾有一个零,但没有显示,但我不相信,因为我能够获得值2018-05- 25 T20:06:58.900Z作为Instant.now().toString()的结果

byqmnocz

byqmnocz1#

当纳秒为零时,它不包含在格式化字符串中,因此输出的格式为“yyyy-MM-dd 'T'HH:mm:ssX”
您可以通过以下方式看到差异:

public static void main(String[] args) throws ParseException {
        final Instant now = Instant.now();
        System.out.println("Now:\t" +  now);

        final Instant zeroedNow = now.with(ChronoField.NANO_OF_SECOND, 0);
        System.out.println("Zeroed:\t" + zeroedNow);
}

输出如下

Now:    2018-05-25T20:23:54.208Z
Zeroed: 2018-05-25T20:23:54Z
jjjwad0x

jjjwad0x2#

您的代码失败是因为Instant.toString()被记录为
使用的格式与DateTimeFormatter.ISO_INSTANT相同。
并根据日期时间格式设置程序.html#ISO_INSTANT
纳秒根据需要输出零、三、六或九位数字
因此,您有千分之一的机会获得一个示例,其中米利斯为000,并且您的代码失败。
无论如何,您的代码不必要地复杂,可以替换为

String formattedDate = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    .withZone(ZoneId.systemDefault())
    .format(Instant.now());

不必将Instant转换为String,只需将其解析为Date,然后再将其转换为String。

brqmpdu1

brqmpdu13#

回答您的问题:"Instant. now()有时格式不同?"。让我们看看www.example.com(). toString()是如何实现的:Instance.now().toString() was implemented:

    • 即时.现在(). toString()源代码**:
public String toString() {
    return DateTimeFormatter.ISO_INSTANT.format(this);
}

java 语
日期时间格式设置程序. ISO_INSTANT
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT

When formatting, the second-of-minute is always output.
 The nano-of-second outputs zero, three, six or nine digits digits as necessary.
    • 从这个javadoc中,我们了解到Instance. now. toString()并不总是24长度**。

如果毫秒是000-〉,它将生成如下格式:
2018年5月25日18时56分9秒20长度

2018年5月25日18:56:09.000Z-24长度
一切都清楚了吗?

cvxl0en2

cvxl0en24#

您可以使用以下命令格式化即时

instant.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))

如果你想使用相同的API并且没有任何标准的方法,你可以考虑使用下面的逻辑

Instant inst = Instant.now()
if(inst.get(ChronoField.MILLI_OF_SECOND) == 0)
inst  = inst.minusMillis(1)

相关问题