Java 以任何符合ISO-8601的格式解析字符串的统一方法
我需要一个统一的方法来解析任何兼容的字符串。不幸的是,Joda和fastxml StdDateFormat都不能完全胜任这项工作 我想解释以下两个属性Java 以任何符合ISO-8601的格式解析字符串的统一方法,java,datetime,timezone,jodatime,fasterxml,Java,Datetime,Timezone,Jodatime,Fasterxml,我需要一个统一的方法来解析任何兼容的字符串。不幸的是,Joda和fastxml StdDateFormat都不能完全胜任这项工作 我想解释以下两个属性 字符串开始 字符串时区 start是符合ISO-8601标准的字符串,可以是任何符合标准的格式,例如“2020-05-15T20:30:52+03:00”或2020-05-15.时区是,例如“欧洲/莫斯科” 所需的逻辑是: 如果时区如果未指定,则将开始扩展到完全限定的UTC,无论其包含什么时区信息。例如,将“2020-05-15T20:30”
- 字符串开始李>
- 字符串时区李>
start
是符合ISO-8601标准的字符串,可以是任何符合标准的格式,例如“2020-05-15T20:30:52+03:00”或2020-05-15.时区是,例如“欧洲/莫斯科”
所需的逻辑是:
如果时区
如果未指定,则将开始
扩展到完全限定的UTC,无论其包含什么时区信息。例如,将“2020-05-15T20:30”扩展到“2020-05-15T20:30:00.000Z”
如果指定了时区
,并且开始
中的时区信息与时区
冲突,则报告错误。例如,时区
=“亚洲/上海”和开始
=“2020-05-15T20:30:52+03:00”
如果指定了时区
,并且与开始
中的时区信息没有冲突,则将开始
扩展到完全合格的ISO-8601格式。例如,时区
=“欧洲/莫斯科”、开始
=“2020-05-15T20:30+03:00”,然后将开始
扩展到“2020-05-15T20:30:00.000+03:00”“
如果指定了时区
,并且开始
没有时区信息,则将时区
添加到开始
,并将其扩展为完全合格的ISO-8601格式。例如,时区
=“欧洲/莫斯科”和开始
=“2020-05-15”,然后将开始
扩展到“2020-05-15T00:00:00.000+03:00”
此代码段主要用于解析符合ISO-8601的字符串。尚未涉及时区
参数。它尝试使用Joda DateTime
和fasterxml StdDateFormat
导入java.util.Date;
导入org.joda.time.DateTime;
导入org.joda.time.DateTimeZone;
导入com.fasterxml.jackson.databind.util.StdDateFormat;
公共类等温线2{
公开无效测试(){
字符串[]输入=新字符串[]{
“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=新的StdDateFormat();
for(字符串输入:输入){
System.out.println();
DateTime输出=null;
布尔值isStdDateFormatFail=false;
试一试{
日期=df.parse(输入);
输出=新日期时间(日期);
System.out.println(“对StdDateFormat:\t\t“+输入有效);
打印(输入、输出);
}捕获(例外e){
isStdDateFormatFail=true;
System.out.println(“======================”);
System.out.println(“对于StdDateFormat:\t\t”+输入无效);
}
如果(isStdDateFormatFail){
试一试{
输出=DateTime.parse(输入);
System.out.println(“对Joda:\t\t”+输入有效);
打印(输入、输出);
}捕获(例外e){
System.out.println(“======================”);
System.out.println(“对于Joda:\t\t”+输入无效);
}
}
}
}
私有void打印(字符串输入、日期时间输出){
System.out.println(“======================”);
System.out.println(“输入:\t\t”+输入);
System.out.println(“输出:\t\t”+输出);
DateTimeZone=output.getZone();
System.out.println(“区域:\t\t”+区域);
}
公共静态void main(字符串[]args){
等温线2试验=新等温线2();
test.test();
}
}
注意我的本地时区是“亚洲/上海”,即+08:00
预期结果
实际结果
封锁问题
有三个阻碍问题
fasterxml StdDateFormat
将原始时区
隐式更改为本地时区
。例如,输入字符串为“2019-06-16T09:30:20+06:00”,输出日期为“2019-06-16T11:30:20.000+08:00”
当start
中不包含时区信息时,Joda
和fasterxml
都会隐式添加本地时区。例如,输入字符串为“2019-06-16T09:30”,输出日期为“2019-06-16T17:30:00.000+08:00”。(我的本地时区是“亚洲/上海”,例如+08:00)我期待的是有机会将时区添加到其中。例如,另一个参数指定为“亚洲/上海”start
=“2019-06-16T09:30”,所需的输出类似于:“2019-06-16T09:30”+“亚洲/上海”=“2019-06-16T09:30:00.000+08:00”
fasterxml
无法解析“20190616T09:30:20+06:00”。Joda和fastermxl都无法解析“20190618T110044Z”
您甚至没有涵盖所有可能的ISO变体,例如:2019-W01-7T03:59Z
。不,我没有。但即使是不完整的变体列表也无法正确处理。您甚至没有涵盖所有可能的ISO变体,例如:2019-W01-7T03:59Z
。不,我没有。但即使是不完整的变体列表也无法得到妥善处理。
=============
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