【问题标题】:Parsing Date Time with optional milliesconds使用可选的毫秒数解析日期时间
【发布时间】:2017-03-07 14:33:51
【问题描述】:

我正在尝试使用 java 将给定的字符串解析为 DateTime,因为该字符串采用以下格式:
YYYY-MM-DDTHH:mm:ss[.s+]Z
毫秒是可选的,可以是小数点后的任意数字。 怎么能简单呢?

【问题讨论】:

  • "并且可以是小数点后的任何数字" - 你真的是这个意思吗? “.1”是指 100 毫秒还是 1 毫秒?那么“.3456”呢?
  • 你试过了吗?请发布您的代码。
  • 如果毫秒是可选的而不是在解析之前从字符串中删除这些
  • 如果它们存在,你需要毫秒吗?

标签: java parsing datetime


【解决方案1】:

首先,您的格式字符串错误。年和日应该小写,即yyyydd,而T是字面量,所以应该加引号,即'T'

假设 “小数点后的任意数量的数字” 您实际上是在谈论 0 到 9 位之间的数字,即纳秒,使用单词 “毫秒” 具有误导性。 小数秒是正确的说法。

要通过 Java 8 Time API 支持不同数量的小数位数,请使用 DateTimeFormatterBuilder,如下所示:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
        .appendPattern("uuuu-MM-dd'T'HH:mm:ss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
        .appendOffset("+HH:mm", "+00:00")
        .toFormatter();
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15+01:00", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.123456789-02:00", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.42000-05:30", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.2468000-05:30", fmt));

输出

2017-03-07T09:47:15+01:00
2017-03-07T09:47:15.123456789-02:00
2017-03-07T09:47:15.420-05:30
2017-03-07T09:47:15.246800-05:30

如您所见,当打印 OffsetDateTime 值时,即当使用 toString() 格式化结果时,尾随零会以 3 个块的增量被截断。

【讨论】:

    【解决方案2】:

    OffsetDateTime.parse() 开箱即用。假设我们有:

        String[] input = {
                "2017-03-07T16:06:13+01:00",
                "2017-03-07T16:06:13.1+01:00",
                "2017-03-07T16:06:13.22+01:00",
                "2017-03-07T16:06:13.333+01:00",
                "2017-03-07T16:06:13.4444+01:00",
                "2017-03-07T16:06:13.55555+01:00",
                "2017-03-07T16:06:13.666666+01:00",
                "2017-03-07T16:06:13.7777777+01:00",
                "2017-03-07T16:06:13.88888888+01:00",
                "2017-03-07T16:06:13.999999999+01:00"
        };
    
        for (String ips : input) {
            OffsetDateTime dt = OffsetDateTime.parse(ips);
            System.out.println(dt);
        }
    

    打印出来:

    2017-03-07T16:06:13+01:00
    2017-03-07T16:06:13.100+01:00
    2017-03-07T16:06:13.220+01:00
    2017-03-07T16:06:13.333+01:00
    2017-03-07T16:06:13.444400+01:00
    2017-03-07T16:06:13.555550+01:00
    2017-03-07T16:06:13.666666+01:00
    2017-03-07T16:06:13.777777700+01:00
    2017-03-07T16:06:13.888888880+01:00
    2017-03-07T16:06:13.999999999+01:00
    

    正如 Andreas 在 his answer 中指出的那样,OffsetDateTime.toString() 会根据需要打印尽可能多的三位小数组,以确保完全准确。您当然可以自己进行格式设置,但我认为这不在问题范围内。

    不过,如果您尝试输入小数点后 10 位(或更多),您确实会得到 DateTimeParseException

    【讨论】:

    • 该死,我什至没有尝试不使用格式化程序。非常好。 +1
    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 2020-08-27
    • 2015-04-01
    • 1970-01-01
    • 2023-02-13
    相关资源
    最近更新 更多