英文:
DateTimeParse Exception
问题
我在解析日期时,代码中一直出现异常错误。日期的格式如下:
Wed May 21 00:00:00 EDT 2008
以下是尝试读取它的代码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy");
Property property = new Property();
property.setSale_date(LocalDateTime.parse(linesplit[8], formatter));
预期结果:一个 LocalDateTime
,值为 2008-05-21T00:00
。
然而实际结果为:
异常线程 "main" 中出现 java.time.format.DateTimeParseException:
在索引 0 处无法解析文本 'Wed May 21 00:00:00 EDT 2008'
我这样做完全错误吗?
英文:
I am constantly getting an exception error in my code when parsing a date.
The Date looks like this:
Wed May 21 00:00:00 EDT 2008
This is the code for trying to read it:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy");
Property property = new Property();
property.setSale_date(LocalDateTime.parse(linesplit[8], formatter));
Expected result: A LocalDateTime
of 2008-05-21T00:00
.
What I got instead:
> Exception in thread "main" java.time.format.DateTimeParseException:
> Text 'Wed May 21 00:00:00 EDT 2008' could not be parsed at index 0
Am I doing this completely wrong?
答案1
得分: 1
恶魔就在细节中。你基本上做得没错,除了:
- 你需要为格式化程序提供区域设置。
- 通过解析成
LocalDateTime
,你正在丢失信息,可能会得到意外的结果。
所以我建议:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
String linesplit8 = "Wed May 21 00:00:00 EDT 2008";
ZonedDateTime zdt = ZonedDateTime.parse(linesplit8, formatter);
System.out.println(zdt);
输出为:
> 2008-05-21T00:00-04:00[America/New_York]
你的字符串是用英语表示的。看起来像是从 Date.toString()
输出的结果(Date
是 Java 8 之前用于表示时间的旧式类)。所以它可能是英语,因为那个 toString
方法总是生成英语输出。因此,如果你的区域设置不是英语区域,解析可能会失败,我认为这就是失败的原因。在这种情况下,使用 Locale.ROOT
代表区域设置中立的英语区域,表示“在这里不应用任何区域设置特定的处理”。
你的字符串包含一个时区缩写,EDT,它是唯一标识时间点的一部分,因此你也会想要获取这部分信息。所以要使用 ZonedDateTime
。
链接
有一些相关/类似的问题,例如:
- how to parse output of new Date().toString()
- java DateTimeFormatterBuilder fails on testtime
- How do I Date format for dd MMM yyyy, as in 01 Apr 2020 [duplicate]
英文:
The devil is in the detail. You are basically doing it correctly, except:
- You need to provide a locale for the formatter.
- By parsing into a
LocalDateTime
you are losing information and possibly getting an unexpected result.
So I suggest:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
String linesplit8 = "Wed May 21 00:00:00 EDT 2008";
ZonedDateTime zdt = ZonedDateTime.parse(linesplit8, formatter);
System.out.println(zdt);
Output is:
> 2008-05-21T00:00-04:00[America/New_York]
Your string is in English. It looks like the output from Date.toString()
(Date
being the old-fashioned class used for times before Java 8). So it’s probably in English because that toString
method always produced English output. So if your locale is not an English-speaking one, parsing is deemed to fail, and I believe this is the reason why it did. In this case it’s appropriate to use Locale.ROOT
for the locale neutral English-speaking locale. A way to say “don’t apply any locale specific processing here”.
Your string contains a time zone abbreviation, EDT, which is part of identifying a unique point in time, so you will want to pick up this part of the information too. Therefore use a ZonedDateTime
.
Links
There are some related/similar questions, for example:
答案2
得分: 1
- 避免使用三个字母的时区标识符。以下是来自Java 6文档的摘录:
三个字母的时区标识符
为了与JDK 1.1.x兼容,还支持一些其他的三个字母的时区标识符(例如“PST”,“CTT”,“AST”)。然而,它们的使用已被弃用,因为同样的缩写通常用于多个时区(例如,“CST”可以是美国的“中部标准时间”和“中国标准时间”),而Java平台只能识别其中之一。
-
第二个重要的事情:永远不要在没有Locale的情况下使用SimpleDateFormat或DateTimeFormatter。
-
我也喜欢在
DateTimeFormatter
中使用u
代替y
,可以参考这里:链接。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz uuuu", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse("Wed May 21 00:00:00 EDT 2008", formatter);
System.out.println(zdt);
输出:
2008-05-21T00:00-04:00[America/New_York]
让我们尝试使用这个格式化器来替换EDT为推荐的 America/New_York的相同日期时间字符串:
ZonedDateTime zdt = ZonedDateTime.parse("Wed May 21 00:00:00 America/New_York 2008", formatter);
System.out.println(zdt);
输出仍然相同。
从**教程: 日期时间中了解更多关于现代日期时间API**的信息。
英文:
- Avoid using the three-letter time zone ID. Given below is an extract from as old as Java 6 documentation:
> Three-letter time zone IDs
>
> For compatibility with JDK 1.1.x, some other three-letter time zone
> IDs (such as "PST", "CTT", "AST") are also supported. However, their
> use is deprecated because the same abbreviation is often used for
> multiple time zones (for example, "CST" could be U.S. "Central
> Standard Time" and "China Standard Time"), and the Java platform can
> then only recognize one of them.
-
The second important thing: Never use SimpleDateFormat or DateTimeFormatter without a Locale.
-
I also prefer u to y with
DateTimeFormatter
.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz uuuu", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse("Wed May 21 00:00:00 EDT 2008", formatter);
System.out.println(zdt);
Output:
2008-05-21T00:00-04:00[America/New_York]
Let's try this formatter for the same date-time string replacing EDT with the recommended America/New_York:
ZonedDateTime zdt = ZonedDateTime.parse("Wed May 21 00:00:00 America/New_York 2008", formatter);
System.out.println(zdt);
The output remains same.
Learn more about the the modern date-time API from Trail: Date Time.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论