java.time.Format.DateTimeFormatter.ISO\u INSTANT的格式字符串?

java.time.Format.DateTimeFormatter.ISO\u INSTANT的格式字符串?,java,java-8,java-time,datetimeformatter,Java,Java 8,Java Time,Datetimeformatter,在Java8的Java.time包中,有一个格式化程序 java.time.format.DateTimeFormatter.ISO\u INSTANT() 它允许在解析和格式化时使用可选的小数秒 以UTC格式格式化或解析瞬间的ISO即时格式化程序, 例如“2011-12-03T10:15:30Z” 这将返回一个不可变的格式化程序 能够格式化和解析ISO-8601即时格式。什么时候 格式化时,始终输出秒数。纳米秒 根据需要输出零位、三位、六位或九位数字。什么时候 解析时,至少需要秒字段的时间。分

在Java8的
Java.time
包中,有一个格式化程序

java.time.format.DateTimeFormatter.ISO\u INSTANT
()

它允许在解析和格式化时使用可选的小数秒

以UTC格式格式化或解析瞬间的ISO即时格式化程序, 例如“2011-12-03T10:15:30Z”

这将返回一个不可变的格式化程序 能够格式化和解析ISO-8601即时格式。什么时候 格式化时,始终输出秒数。纳米秒 根据需要输出零位、三位、六位或九位数字。什么时候 解析时,至少需要秒字段的时间。分数的 从0到9的秒数被解析。本地化的十进制样式是 没有用

可用于创建此格式化程序的格式字符串是什么?我需要存储
字符串
,但不能存储
日期时间格式
,因为后者不可序列化

具体来说,我想知道如何表示小数秒(包括数字前面的
)。我知道
S
表示秒的分数,
X
表示区域偏移,但我不知道如何将它们组合在一起

S       fraction-of-second          fraction          978
X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;

我能找到的最接近的东西是。但是,我不知道/找不到任何方法来获取0/3/6/9位十进制行为

我敦促你考虑如果你正在解决正确的问题,即:为什么你需要序列化格式化程序本身?格式化程序不是数据,而是逻辑。序列化您的数据,并在整个项目中使用一致的格式设置方案——您甚至可以集中时间序列化/反序列化,这样读/写的类实际上根本不需要进行格式设置


另一种方法是找到一种序列化格式化程序的方法,并将记录和解释序列化时间内使用的格式化程序的负担强加给每个读写器。您将自己置于所有相关类之间共享的格式的硬依赖中。

我能找到的最接近的东西是。但是,我不知道/找不到任何方法来获取0/3/6/9位十进制行为

我敦促你考虑如果你正在解决正确的问题,即:为什么你需要序列化格式化程序本身?格式化程序不是数据,而是逻辑。序列化您的数据,并在整个项目中使用一致的格式设置方案——您甚至可以集中时间序列化/反序列化,这样读/写的类实际上根本不需要进行格式设置


另一种方法是找到一种序列化格式化程序的方法,并将记录和解释序列化时间内使用的格式化程序的负担强加给每个读写器。您将自己置于所有相关类之间共享的格式的硬依赖中。

我找不到直接等效的格式模式字符串。正如@JB Nizet所建议的那样,这甚至可能是不可能的

但是,我发现我可以在
字符串
模式中使用可选的节标记
[
]
,以获得大致的行为:

"yyyy-MM-dd'T'HH:mm:ss[.SSS]X"
这可以处理以下输入字符串:

"2019-09-02T12:38:16Z"
"2019-09-02T12:38:16.294Z"
这使得分数秒分量是可选的

然而,对我来说仍然有一个限制——分数秒,虽然现在是可选的,但如果存在的话,必须正好是3位数。我不知道是什么样的
字符串
模式可以使
DateTimeFormatter
接受0-9个小数秒数字

为了克服这个限制,现在我使用下面的解决方案——任何分数秒分量,如果存在,都将首先“规范化”为3位数。这 在将输入字符串传递到
DataTimeFormatter
进行解析之前,通过方法
OptionalCanonicalizeFractilSecond()
(代码如下所示)完成。这 到目前为止,这种方法对我有效

因此,作为输入模式的一部分,给定
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;
}
/*
*显然java.time.format.DateTimeFormatter无法处理
*分数秒数可变的字符串模式
*数字化。此方法“规范化”任何此类组件
*到3位数
*/
私有字符串选项CanonicalizeFractionalSecond(字符串输入){
如果(!formatPattern.contains(“mm:ss[.SSS]”){
//模式中没有分数秒分量
返回输入;//无需进行任何更改
}
Pattern regexpatern=Pattern.compile(^(.*)(\\d\\d:\\d\\d)(\\\.\\d+)(.*);
Matcher Matcher=regexpatern.Matcher(input.trim());
如果(!matcher.matches()){
//输入字符串中没有分数秒复合词
返回输入;
}
字符串前缀=matcher.group(1);
字符串minuteSecondString=matcher.group(2);
String-secondstring=matcher.group(3);
字符串后缀=matcher.group(4);
弦炮;
if(分馏SecondString.length()==2){
canonFss=fractionalSecondString+“00”;//用00填充
}else if(分数secondstring.length()==3){
canonFss=SectionLSeCondString+“0”//用0填充
}else if(分数secondString.length()==4){
canonFss=SectionLSeCondString;//原样
}else if(分馏lseCondString.length()>4

&&我找不到直接等效格式模式字符串。正如@JB Nizet所建议的,这甚至可能不可能

但是,我发现我可以在
字符串
模式中使用可选的节标记
[
]
,以获得大致的行为:

"yyyy-MM-dd'T'HH:mm:ss[.SSS]X"
这可以处理以下输入字符串:

"2019-09-02T12:38:16Z"
"2019-09-02T12:38:16.294Z"
这使得分数秒分量是可选的

然而,对我来说仍然有一个限制——分数秒,虽然现在是可选的,但如果存在的话,必须正好是3位数。我不知道是什么