我需要一个统一的方法来解析任何符合ISO-8601的字符串。不幸的是,Joda或fastxml StdDateFormat都不具备这样做的资格。
我想解释以下两个属性
start
是符合ISO-8601的字符串,可以是任何符合标准的格式,例如“ 2020-05-15T20:30:52 + 03:00”或2020-05-15”。{{1 }}是IANA timezone,例如“欧洲/莫斯科”。
所需的逻辑是:
如果未指定timezone
,则将timezone
扩展为完全合格的UTC,而不考虑其包括的时区信息。例如,将“ 2020-05-15T20:30”扩展到“ 2020-05-15T20:30:00.000Z”。
如果指定了start
,并且timezone
中的时区信息与start
冲突,则报告错误。例如,timezone
=“亚洲/上海”和timezone
=“ 2020-05-15T20:30:52 + 03:00”。
如果指定了start
,并且与timezone
中的时区信息没有冲突,则将start
扩展为标准ISO-8601格式。例如,start
=“欧洲/莫斯科”,timezone
=“ 2020-05-15T20:30 + 03:00”,然后将start
扩展为“ 2020-05-15T20: 30:00.000 + 03:00“。
如果指定了start
,并且timezone
没有时区信息,则将start
添加到timezone
并将其扩展为完全合格的ISO-8601格式。例如,start
=“ Europe / Moscow”和timezone
=“ 2020-05-15”,然后将start
扩展到“ 2020-05-15T00:00:00.000 + 03: 00”。
此代码段着重于解析符合ISO-8601的字符串。尚无start
参数涉及。它尝试使用timezone
和Joda DateTime
。
fasterxml StdDateFormat
注意,我的本地时区是“亚洲/上海”,即+08:00
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import com.fasterxml.jackson.databind.util.StdDateFormat;
public class ISOTest2 {
public void test() {
String [] inputs = new String [] {
"2019-06-16T09:30:20+06:00",
"2019-06-16T09:30Z",
"2019-06-16T09:30:20",
"2019-06-16T09:30",
"2019-06-16T",
"2019-06-16",
"20190616T09:30:20+06:00",
"20190618T110044Z"
};
StdDateFormat df = new StdDateFormat();
for (String input : inputs) {
System.out.println();
DateTime output = null;
boolean isStdDateFormatFail = false;
try {
Date date = df.parse(input);
output = new DateTime(date);
System.out.println("Valid for StdDateFormat:\t\t" + input);
print(input, output);
} catch (Exception e) {
isStdDateFormatFail = true;
System.out.println("=============");
System.out.println("Invalid for StdDateFormat:\t\t" + input);
}
if (isStdDateFormatFail) {
try {
output = DateTime.parse(input);
System.out.println("Valid for Joda:\t\t" + input);
print(input, output);
} catch (Exception e) {
System.out.println("=============");
System.out.println("Invalid for Joda:\t\t" + input);
}
}
}
}
private void print(String input, DateTime output) {
System.out.println("=============");
System.out.println("Input:\t\t" + input);
System.out.println("Output:\t\t" + output);
DateTimeZone zone = output.getZone();
System.out.println("Zone:\t\t" + zone);
}
public static void main(String[] args) {
ISOTest2 test = new ISOTest2();
test.test();
}
}
=============
Input: 2019-06-16T09:30:20+06:00
Output: 2019-06-16T09:30:20.000+06:00
Zone: +0600
=============
Input: 2019-06-16T09:30Z
Output: 2019-06-16T09:30:00.000Z
Zone: UTC
=============
Input: 2019-06-16T09:30:20
Output: 2019-06-16T09:30:20.000Z
Zone: UTC
=============
Input: 2019-06-16T09:30
Output: 2019-06-16T09:30:00.000Z
Zone: UTC
=============
Input: 2019-06-16T
Output: 2019-06-16T00:00:00.000Z
Zone: UTC
=============
Input: 2019-06-16
Output: 2019-06-16T00:00:00.000Z
Zone: UTC
=============
Input: 20190616T09:30:20+06:00
Output: 2019-06-16T09:30:20.000+06:00
Zone: +0600
=============
Input: 20190618T110044Z
Output: 2019-06-18T11:00:44.000Z
Zone: UTC
存在三个阻止问题。
Valid for StdDateFormat: 2019-06-16T09:30:20+06:00
=============
Input: 2019-06-16T09:30:20+06:00
Output: 2019-06-16T11:30:20.000+08:00
Zone: Asia/Shanghai
Valid for StdDateFormat: 2019-06-16T09:30Z
=============
Input: 2019-06-16T09:30Z
Output: 2019-06-16T17:30:00.000+08:00
Zone: Asia/Shanghai
Valid for StdDateFormat: 2019-06-16T09:30:20
=============
Input: 2019-06-16T09:30:20
Output: 2019-06-16T17:30:20.000+08:00
Zone: Asia/Shanghai
Valid for StdDateFormat: 2019-06-16T09:30
=============
Input: 2019-06-16T09:30
Output: 2019-06-16T17:30:00.000+08:00
Zone: Asia/Shanghai
=============
Invalid for StdDateFormat: 2019-06-16T
Valid for Joda: 2019-06-16T
=============
Input: 2019-06-16T
Output: 2019-06-16T00:00:00.000+08:00
Zone: Asia/Shanghai
Valid for StdDateFormat: 2019-06-16
=============
Input: 2019-06-16
Output: 2019-06-16T08:00:00.000+08:00
Zone: Asia/Shanghai
=============
Invalid for StdDateFormat: 20190616T09:30:20+06:00
Valid for Joda: 20190616T09:30:20+06:00
=============
Input: 20190616T09:30:20+06:00
Output: 20190616-01-01T09:30:20.000+06:00
Zone: +06:00
=============
Invalid for StdDateFormat: 20190618T110044Z
=============
Invalid for Joda: 20190618T110044Z
会将fasterxml StdDateFormat
隐式更改为original timezone
。例如,输入字符串为“ 2019-06-16T09:30:20 + 06:00”,输出日期为“ 2019-06-16T11:30:20.000 + 08:00”。
当local timezone
中不包含时区信息时,start
和Joda
都会隐式添加本地时区。例如,输入字符串为“ 2019-06-16T09:30”,输出日期为“ 2019-06-16T17:30:00.000 + 08:00”。 (我的本地时区是“亚洲/上海”,例如+08:00)我期望有机会在其中添加fasterxml
。例如,还有另一个参数指定为“ Asia / Shanghai”,timezone
=“ 2019-06-16T09:30”,所需的输出类似于:“ 2019-06-16T09:30” +“ Asia / Shanghai“ =” 2019-06-16T09:30:00.000 + 08:00“。
start
无法解析“ 20190616T09:30:20 + 06:00”。 Joda和fastmxl都无法解析“ 20190618T110044Z”。