时区有冒号时如何解决解析异常?
How to solve parse exception when timezone has colon?
我从网络服务接收 DateTime
作为 String
。 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
。但是,响应 DateTime 的时区部分中的冒号导致了问题。 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、SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*.
解决方案使用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
检查How to use OffsetDateTime
in JDBC?。
详细了解 java.time
,modern Date-Time API* 来自 Trail:日期时间.
使用遗留解决方案 API:
SimpleDateFormat
没有指定可选模式的功能,我们使用方括号和 DateTimeFormatter
的方式。在这种情况下,您可以创建 SimpleDateFormat
的多个实例并尝试每个实例。
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);
}
}
}
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and 。
我从网络服务接收 DateTime
作为 String
。 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
。但是,响应 DateTime 的时区部分中的冒号导致了问题。 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、SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*.
解决方案使用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
检查How to use OffsetDateTime
in JDBC?。
详细了解 java.time
,modern Date-Time API* 来自 Trail:日期时间.
使用遗留解决方案 API:
SimpleDateFormat
没有指定可选模式的功能,我们使用方括号和 DateTimeFormatter
的方式。在这种情况下,您可以创建 SimpleDateFormat
的多个实例并尝试每个实例。
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);
}
}
}
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and