问题描述
我正在尝试以以下格式将传入的 ISO 日期(如 (2021-02-15T00:00:00.000Z))显示到 Textview:“dd MM yyyy”。 但是在解析日期时出现以下错误。
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.text.ParseException: Unparseable date: "2021-02-15T00:00:00.000Z"
at java.text.DateFormat.parse(DateFormat.java:362)
这是 Kotlin 代码:
val format = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.getDefault()
)
val initialConvertedDate = format.parse(customfield.value)
val simpleDateFormat = SimpleDateFormat(
"dd MM yyyy",Locale.getDefault()
)
val finalDate = simpleDateFormat.format(initialConvertedDate)
tv2.text = finalDate
解决方法
使用模式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
,其中 X
真正代表 timezone offset。在您的日期时间字符串中,时区偏移量是 Z
,它代表祖鲁语并指定 UTC(时区偏移量 +00:00
小时)。
您使用的格式有两个问题:
- 它使
Z
作为字符文字,因此它不代表时区偏移。 - 它没有指定秒的小数部分,即
SSS
。
演示:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String args[]) throws ParseException {
String strDateTime = "2021-02-15T00:00:00.000Z";
SimpleDateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX",Locale.getDefault());
Date date = sdfInput.parse(strDateTime);
SimpleDateFormat sdfOutput = new SimpleDateFormat("dd MM yyyy");
sdfOutput.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String formatted = sdfOutput.format(date);
System.out.println(formatted);
}
}
输出:
15 02 2021
请注意,旧的日期时间 API(java.util
日期时间类型及其格式 API,SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API*。
使用现代日期时间 API 的演示:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String args[]) {
String strDateTime = "2021-02-15T00:00:00.000Z";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("dd MM yyyy");
String formatted = dtfOutput.format(odt);
System.out.println(formatted);
}
}
输出:
2021-02-15T00:00Z
15 02 2021
请注意,现代日期时间 API 基于 ISO-8601,因此您无需显式使用 DateTimeFormatter
来解析 ISO- 中已存在的日期时间字符串8601 格式。
从 modern date-time API 中了解有关 Trail: Date Time* 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。