Java 时区有冒号时如何解决解析异常?
我正在以Java 时区有冒号时如何解决解析异常?,java,datetime,simpledateformat,date-format,Java,Datetime,Simpledateformat,Date Format,我正在以字符串的形式从Web服务接收DateTime。此DateTime字符串的一个示例是:“DateTime”:“2021-06-06T04:54:41-04:00” 这个2021-06-06T04:54:41-04:00或多或少地匹配ISO-8601格式,所以我使用了这个模式来解析它:yyyy-MM-dd'T'HH:MM:ssZ。但是,响应日期时间的时区部分中的冒号会导致问题2021-06-06T04:54:41-04:00给出了解析异常,但2021-06-06T04:54:41-0400进
字符串的形式从Web服务接收DateTime
。此DateTime
字符串的一个示例是:“DateTime”:“2021-06-06T04:54:41-04:00”
这个2021-06-06T04:54:41-04:00
或多或少地匹配ISO-8601格式,所以我使用了这个模式来解析它:yyyy-MM-dd'T'HH:MM:ssZ
。但是,响应日期时间的时区部分中的冒号会导致问题2021-06-06T04:54:41-04:00给出了解析异常,但2021-06-06T04:54:41-0400进行了解析
下面的代码应该更好地解释它:
public void stringToDate() {
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ"; //ISO - 8601 Format
TimeZone timeZoneEST = TimeZone.getTimeZone("US/Eastern");
SimpleDateFormat sdf = new SimpleDateFormat(pattern, new Locale("en", "US"));
sdf.setLenient(false);
sdf.setTimeZone(timeZoneEST);
String timeFromWebService = "2021-06-06T04:54:41-04:00";
try {
Date parsedDate = sdf.parse(timeFromWebService); // not working because of colon in timezone part
System.out.println(parsedDate);
} catch (ParseException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000); //sleep to avoid interleaving output from stacktrace (above) and syso (below)
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String timeFromWebServiceModified = "2021-06-06T04:54:41-0400"; //removed colon from timezone part
try {
Date parsedDate = sdf.parse(timeFromWebServiceModified); // working because colon is removed in timezone part
System.out.println(parsedDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
我希望在不修改响应的情况下处理此解析DateTime
。关于如何解析原始DateTime
的任何建议。任何关于使用哪种模式的建议都将非常有用。java.util
日期时间API及其格式化API,SimpleDataFormat
已经过时且容易出错。建议完全停止使用,并切换到*
解决方案使用java.time
,现代API:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
//Test
Stream.of(
"2021-06-06T04:54:41-04:00",
"2021-06-06T04:54:41-0400",
"2021-06-06T04:54:41-04",
"2021-06-06T04:54:41Z"
).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
}
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z
输出:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
//Test
Stream.of(
"2021-06-06T04:54:41-04:00",
"2021-06-06T04:54:41-0400",
"2021-06-06T04:54:41-04",
"2021-06-06T04:54:41Z"
).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
}
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z
检查
了解更多关于java.time
、来自的*
使用传统API的解决方案:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d'T'H:m:s[XXX][XX][X]", Locale.ENGLISH);
//Test
Stream.of(
"2021-06-06T04:54:41-04:00",
"2021-06-06T04:54:41-0400",
"2021-06-06T04:54:41-04",
"2021-06-06T04:54:41Z"
).forEach(s -> System.out.println(OffsetDateTime.parse(s, dtf)));
}
}
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41-04:00
2021-06-06T04:54:41Z
SimpleDataFormat
没有指定可选模式的功能,就像我们使用方括号和DateTimeFormatter
一样。在这种情况下,您可以创建多个SimpleDataFormat
实例,并对每个实例进行尝试
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
SimpleDateFormat sfdArr[] = {
new SimpleDateFormat("y-M-d'T'H:m:sXXX", Locale.ENGLISH),
new SimpleDateFormat("y-M-d'T'H:m:sXX", Locale.ENGLISH),
new SimpleDateFormat("y-M-d'T'H:m:sX", Locale.ENGLISH)
};
String []strDateTimeArr = {
"2021-06-06T04:54:41-04:00",
"2021-06-06T04:54:41-0400",
"2021-06-06T04:54:41-04",
"2021-06-06T04:54:41Z"
};
for(String s : strDateTimeArr) {
Date date = null;
for(SimpleDateFormat sdf : sfdArr) {
try {
date = sdf.parse(s);
}catch(ParseException e) {
//...
}
}
System.out.println(date);
}
}
}
*无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认。
我建议您不要使用时区
、简化格式
和日期
。这些类设计得很糟糕,而且很早就过时了,SimpleDateFormat
尤其是出了名的麻烦。相反,只需使用OffsetDateTime
from及其一个argparse
方法。我将继续讨论j8+api:-)。这是我在j8+api中看到的另一个问题——如果你认为值得的话,你能投票支持Q吗。