Java SimpleDateFormat 抛出 ParseException:在 Windows 但在 Mac 上无法解析的日期
Java SimpleDateFormat throwing ParseException: Unparseable date on Windows but not on Mac
我有以下方法:
public static Date convertFromWowInterface(String wowinterfaceFormat){
Date date = null;
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
date = dateFormat.parse(wowinterfaceFormat);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
传入的字符串格式为:
"08-11-19 07:00 AM"
显然没有引号。现在上面的方法在我的 mac 上工作得很好,但是当我的一些用户使用该程序时(在 Windows 上)他们得到异常:
java.text.ParseException: Unparseable date: "08-11-19 07:00 AM"
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
OS 有区别吗?还是有其他事情在起作用?据我所知,SimpleDateFormat 与输入字符串完全匹配?
当我切换到不同的语言环境时,我可以重现该问题。
这是我的演示程序:
import java.util.*;
import java.text.*;
public class YourCode {
public static void main(String[] args) throws Exception {
for (String a : args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
Date d = dateFormat.parse(a);
System.out.println(d);
}
}
}
当我 运行 它在美国英语语言环境下工作时:
robert@saaz:~$ LC_ALL="en_US.UTF-8" java YourCode "08-11-19 07:00 AM"
Sun Aug 11 07:00:00 CDT 2019
当我切换到例如使用 24 小时制而不是 AM/PM 的德语语言环境时,我看到了异常。
robert@saaz:~$ LC_ALL="de_DE.UTF-8" java YourCode "08-11-19 07:00 AM"
Exception in thread "main" java.text.ParseException: Unparseable date: "08-11-19 07:00 AM"
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
at YourCode.main(YourCode.java:8)
要解决这个问题,请在创建 SimpleDateFormat
时指定语言环境。变化
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
到
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a", Locale.US);
tl;博士
➡ 指定用于翻译AM
/PM
的语言。
使用现代java.time类。永远不要使用 Date
& SimpleDateFormat
.
LocalDateTime
.parse(
"08-11-19 07:00 AM" ,
DateTimeFormatter.ofPattern( "MM-dd-uu hh:mm a" ).withLocale( Locale.US )
)
java.time
您正在使用糟糕的日期时间 类,它在几年前被 JSR 310 中定义的现代 java.time 类 所取代。
定义格式模式以匹配您的输入。指定一个 Locale
来确定翻译 "AM"/"PM" 所需的人类语言和文化规范。
String input = "08-11-19 07:00 AM" ;
Locale locale = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uu hh:mm a" ).withLocale( locale ) ;
将输入解析为 LocalDateTime
,因为它缺少时区指示符或与 UTC 的偏移量。因此,它没有实际意义。我们不知道该数据的发布者指的是东京早上 7 点、卡萨布兰卡早上 7 点,还是蒙特利尔早上 7 点——所有时间都非常不同,相隔几个小时。
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
运行 此代码位于 IdeOne.com。
ldt.toString(): 2019-08-11T07:00
最后,让您的数据发布者了解 ISO 8601 将日期时间值作为文本交换的标准格式。您当前使用的模式是一个糟糕的选择。
我有以下方法:
public static Date convertFromWowInterface(String wowinterfaceFormat){
Date date = null;
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
date = dateFormat.parse(wowinterfaceFormat);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
传入的字符串格式为:
"08-11-19 07:00 AM"
显然没有引号。现在上面的方法在我的 mac 上工作得很好,但是当我的一些用户使用该程序时(在 Windows 上)他们得到异常:
java.text.ParseException: Unparseable date: "08-11-19 07:00 AM"
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
OS 有区别吗?还是有其他事情在起作用?据我所知,SimpleDateFormat 与输入字符串完全匹配?
当我切换到不同的语言环境时,我可以重现该问题。
这是我的演示程序:
import java.util.*;
import java.text.*;
public class YourCode {
public static void main(String[] args) throws Exception {
for (String a : args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
Date d = dateFormat.parse(a);
System.out.println(d);
}
}
}
当我 运行 它在美国英语语言环境下工作时:
robert@saaz:~$ LC_ALL="en_US.UTF-8" java YourCode "08-11-19 07:00 AM"
Sun Aug 11 07:00:00 CDT 2019
当我切换到例如使用 24 小时制而不是 AM/PM 的德语语言环境时,我看到了异常。
robert@saaz:~$ LC_ALL="de_DE.UTF-8" java YourCode "08-11-19 07:00 AM"
Exception in thread "main" java.text.ParseException: Unparseable date: "08-11-19 07:00 AM"
at java.base/java.text.DateFormat.parse(DateFormat.java:395)
at YourCode.main(YourCode.java:8)
要解决这个问题,请在创建 SimpleDateFormat
时指定语言环境。变化
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a");
到
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yy hh:mm a", Locale.US);
tl;博士
➡ 指定用于翻译AM
/PM
的语言。
使用现代java.time类。永远不要使用 Date
& SimpleDateFormat
.
LocalDateTime
.parse(
"08-11-19 07:00 AM" ,
DateTimeFormatter.ofPattern( "MM-dd-uu hh:mm a" ).withLocale( Locale.US )
)
java.time
您正在使用糟糕的日期时间 类,它在几年前被 JSR 310 中定义的现代 java.time 类 所取代。
定义格式模式以匹配您的输入。指定一个 Locale
来确定翻译 "AM"/"PM" 所需的人类语言和文化规范。
String input = "08-11-19 07:00 AM" ;
Locale locale = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uu hh:mm a" ).withLocale( locale ) ;
将输入解析为 LocalDateTime
,因为它缺少时区指示符或与 UTC 的偏移量。因此,它没有实际意义。我们不知道该数据的发布者指的是东京早上 7 点、卡萨布兰卡早上 7 点,还是蒙特利尔早上 7 点——所有时间都非常不同,相隔几个小时。
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
运行 此代码位于 IdeOne.com。
ldt.toString(): 2019-08-11T07:00
最后,让您的数据发布者了解 ISO 8601 将日期时间值作为文本交换的标准格式。您当前使用的模式是一个糟糕的选择。