>我有以下方法:
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)
操作系统在这里有什么不同吗?还是有别的东西在起作用?据我所知,简单日期格式与输入字符串完全匹配?
当我切换到不同的语言环境时,我可以重现该问题。
这是我的演示程序:
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 标准格式。您正在使用的当前模式是一个糟糕的选择。