Java SimpleDateFormat抛出ParseException:在Windows上无法解析日期,但在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)

操作系统在这里有什么不同吗?还是有别的东西在起作用?据我所知,简单日期格式与输入字符串完全匹配?

当我切换到不同的语言环境时,我可以重现该问题。

这是我的演示程序:

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 标准格式。您正在使用的当前模式是一个糟糕的选择。

最新更新