Java 8 DateTimeFormatter 解析不同重要性的可选小数秒
Java 8 DateTimeFormatter parsing for optional fractional seconds of varying significance
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
测试日期时间 String
的解析,其中 具有不同意义的可选小数秒 。 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 次),还是我的模式有 'smarter' 方式?
编辑最后我找到了自己的答案...仍然会把这个留一天没有答案,看看是否还有其他方法。
太棒了,又进行了 15 分钟的故障排除:
private static final DateTimeFormatter FORMATTER =
new DateTimeFormatterBuilder().appendPattern(BASE_PATTERN) // .parseLenient()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).toFormatter();
编辑 parseLenient()
是 .
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
测试日期时间 String
的解析,其中 具有不同意义的可选小数秒 。 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 次),还是我的模式有 'smarter' 方式?
编辑最后我找到了自己的答案...仍然会把这个留一天没有答案,看看是否还有其他方法。
太棒了,又进行了 15 分钟的故障排除:
private static final DateTimeFormatter FORMATTER =
new DateTimeFormatterBuilder().appendPattern(BASE_PATTERN) // .parseLenient()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).toFormatter();
编辑 parseLenient()
是