我找不到直接等效的格式模式字符串。正如@JB Nizet 所建议的那样,这甚至可能是不可能的。
但是,我发现我可以使用可选的部分标记和[
模式来获得近似的行为:]
String
"yyyy-MM-dd'T'HH:mm:ss[.SSS]X"
这可以处理以下输入字符串:
"2019-09-02T12:38:16Z"
"2019-09-02T12:38:16.294Z"
这使得小数秒部分是可选的。
但是,对我来说仍然有一个限制——小数秒虽然现在是可选的,但如果存在,则必须恰好是 3 位数。我不知道String
可以DateTimeFormatter
接受 0-9 小数秒数的模式是什么。
为了克服这个限制,现在我使用以下解决方案——任何小数秒分量(如果存在)首先被“规范化”为 3 位数字。这是在将输入字符串传递给解析之前通过一种方法optionalCanonicalizeFractionalSecond()
(代码如下所示)完成的。DataTimeFormatter
到目前为止,这种方法对我有效。
所以mm:ss[.SSS]
作为输入模式的一部分给出:
`12:30.123` will be canon'ed as `12:30.123`
`12:30.12` will be canon'ed as `12:30.120`
`12:30.1` will be canon'ed as `12:30.100`
`12:30.123456789` will be canon'ed as `12:30.123`
示例代码
/*
* Apparently java.time.format.DateTimeFormatter cannot handling
* a string pattern with variable number of fractional-second
* digitit. This method "canonicalize" any such component
* to 3 digits
*/
private String optionalCanonicalizeFractionalSecond(String input) {
if (!formatPattern.contains("mm:ss[.SSS]")) {
// no fractional-second component in the pattern
return input; // no need to make any changes
}
Pattern regexPattern = Pattern.compile("^(.*)(\\d\\d:\\d\\d)(\\.\\d+)(.*)$");
Matcher matcher = regexPattern.matcher(input.trim());
if (!matcher.matches()) {
// no fractional-second componet in the input string
return input;
}
String prefix = matcher.group(1);
String minuteSecondString = matcher.group(2);
String fractionalSecondString = matcher.group(3);
String suffix = matcher.group(4);
String canonFss;
if (fractionalSecondString.length() == 2) {
canonFss = fractionalSecondString + "00"; // padding with 00
} else if (fractionalSecondString.length() == 3) {
canonFss = fractionalSecondString + "0"; // padding with 0
} else if (fractionalSecondString.length() == 4) {
canonFss = fractionalSecondString; // as is
} else if (fractionalSecondString.length() > 4
&& fractionalSecondString.length() <= 10) {
canonFss = fractionalSecondString.substring(0,4); // truncate to 3 digits
} else {
return input;
}
return prefix + minuteSecondString + canonFss + suffix;
}