Java 8 DateTimeFormatter 解析不同重要性的可选小数秒

标签 java java-time datetime-parsing

我的 MCVE(作为 TestNG 单元测试):

public class MyDateTimeFormatterTest {

    private static final String BASE_PATTERN = "yyyy/MM/dd HH:mm:ss";
    private static final DateTimeFormatter FORMATTER =
            DateTimeFormatter.ofPattern(BASE_PATTERN + "[.SSSSSSSSS]");
    private static final LocalDateTime TEST_INPUT =
            LocalDateTime.of(2015, 5, 4, 12, 34, 56, 123456789);

    @DataProvider(name = "test-cases")
    public Iterator<Object[]> getTestCases() {
        return Arrays.asList(testFor("", ChronoUnit.SECONDS),
                testFor(".SSS", ChronoUnit.MILLIS),
                testFor(".SSSSSS", ChronoUnit.MICROS),
                testFor(".SSSSSSSSS", ChronoUnit.NANOS)).iterator();
    }

    @Test(dataProvider = "test-cases")
    public void testWithDefaultResolution(String input, LocalDateTime output) {
        assertThat(FORMATTER.parse(input, LocalDateTime::from), equalTo(output));
    }

    private Object[] testFor(String patternSuffix, TemporalUnit truncatedTo) {
        return new Object[] { DateTimeFormatter.ofPattern(BASE_PATTERN + patternSuffix)
                .format(TEST_INPUT), TEST_INPUT.truncatedTo(truncatedTo) };
    }
}

我正在尝试使用 DateTimeFormatter 测试日期时间 Stringoptional fractional seconds of varying significance 的解析。 Javadoc 的相关部分如下:

Fraction: Outputs the nano-of-second field as a fraction-of-second. The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9. If it is less than 9, then the nano-of-second value is truncated, with only the most significant digits being output.

基于我有限的理解,我使用 [...] 将小数秒标记为可选,并且由于我对不同的意义感兴趣,我认为我应该坚持使用 SSSSSSSSS.

但是,单元测试在解析最多 毫秒和微秒时失败,即第二种和第三种情况。将 ResolverStyle 更改为 LENIENT 在这里没有帮助,因为它在解析阶段失败,而不是解析阶段。

我可以知道应该考虑哪些方法来解决我的问题吗?我应该使用 DateTimeFormatterBuilder 来选择性地指定每个小数位(9 次),还是我的模式有一种“更智能”的方式?

edit 最后我找到了自己的答案......仍然会把它留一天没有答案,看看是否有其他方法。

最佳答案

太棒了,另外 15 分钟的故障排除产生了这个:

private static final DateTimeFormatter FORMATTER = 
    new DateTimeFormatterBuilder().appendPattern(BASE_PATTERN) // .parseLenient()
        .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).toFormatter();

编辑 parseLenient()optional .

关于Java 8 DateTimeFormatter 解析不同重要性的可选小数秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30090710/

相关文章:

java - 当元素应该对 webdriver 可见时收到 ElementNotVisibleException

Java 日期和时间 : How do I make plus() and until() to be each others inverse

java - ZoneIds 在其他平台上的可用性

.net - 为什么 DateTime.ParseExact 不使用尾随 Z 解析 UTC 格式?

javascript - 解析Javascript中自定义格式的 'Date & Time'字符串

java - 在 Java 中区分关闭比 Runtime.setShutdownHook()

java - 有人可以解释我的代码有什么问题吗?

java - 为什么 SimpleDateFormat setTimeZone 不会因无效时区而引发错误

java - cookie.setMaxAge 奇怪的行为

java - 哪个时区是 java.sql.Date toLocalDate 使用