Java - 无法解析的日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6154772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - Unparseable date
提问by Amokrane Chentir
I am trying to parse a date, but I am oddly getting an exception.
我正在尝试解析一个日期,但奇怪的是我遇到了一个例外。
This is the code:
这是代码:
import java.util.Date;
String strDate = "Wed, 09 Feb 2011 12:34:27";
Date date;
SimpleDateFormat FORMATTER = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
try {
date = FORMATTER.parse(strDate.trim());
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
The exception is:
例外是:
java.text.ParseException: Unparseable date: "Wed, 09 Feb 2011 12:34:27" at java.text.DateFormat.parse(DateFormat.java:337) at DateTest.main(DateTest.java:17)
java.text.ParseException:无法解析的日期:“Wed, 09 Feb 2011 12:34:27” at java.text.DateFormat.parse(DateFormat.java:337) at DateTest.main(DateTest.java:17)
I have read the documentationand I think my pattern is correct. So I don't understand...
我已阅读文档,我认为我的模式是正确的。所以我不明白...
Any idea?
任何的想法?
Thanks!
谢谢!
回答by a_horse_with_no_name
It's probably because of the default locale on your computer which is not english.
这可能是因为您计算机上的默认语言环境不是英语。
You should use:
你应该使用:
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH);
instead.
反而。
回答by Basil Bourque
tl;dr
tl;博士
java.util.Date.from (
LocalDateTime.parse(
"Wed, 09 Feb 2011 12:34:27" ,
DateTimeFormatter.ofPattern( "EEE, dd MMM uuuu HH:mm:ss" , Locale.US )
).atZone( ZoneId.of( "America/Montreal" ) )
.toInstant()
)
Details
细节
The Question and other Answer both use outdated troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
问题和其他答案都使用过时的麻烦的旧日期时间类,这些类现在是遗留的,由 java.time 类取代。
Using java.time
使用 java.time
The input string lacks any indication of a time zone or offset-from-UTC. So we parse as an OffsetDateTime
.
输入字符串缺少时区或UTC 偏移量的任何指示。所以我们解析为OffsetDateTime
.
Specify a Locale
to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
指定 aLocale
以确定 (a) 用于翻译日名、月名等的人类语言,以及 (b) 决定缩写、大写、标点符号、分隔符等问题的文化规范。
String input = "Wed, 09 Feb 2011 12:34:27" ;
Locale l = Locale.US ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE, dd MMM uuuu HH:mm:ss" , l ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ldt.toString(): 2011-02-09T12:34:27
ldt.toString(): 2011-02-09T12:34:27
Time Zone
时区
Both the Question and other Answer ignore the crucial issue of time zone.
问题和其他答案都忽略了时区的关键问题。
The input string lacks a time zone or offset. We parsed as an LocalDateTime
which is nota moment on the timeline, only a vague idea about possible moments. Like saying "Christmas begins at midnight on December 25, 2017", that has no meaning until you place it in the context of a particular time zone. Christmas comes much earlier in Auckland New Zealand than it does in Paris France, and much later still in Montréal Québec.
输入字符串缺少时区或偏移量。我们解析为LocalDateTime
which不是时间轴上的时刻,只是对可能时刻的模糊概念。就像说“圣诞节从 2017 年 12 月 25 日午夜开始”一样,除非您将其置于特定时区的上下文中,否则这没有任何意义。新西兰奥克兰的圣诞节比法国巴黎的圣诞节要早得多,而魁北克蒙特利尔的圣诞节则要晚得多。
If you know the intended time zone, assign a ZoneId
to produce a ZonedDateTime
.
如果您知道预期的时区,请分配 aZoneId
以生成ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ldt.atZone( z ); // Assigning a time zone to determine an actual moment on the timeline.
Converting
转换
Best to avoid the troublesome old legacy date-time classes. But if you must interact with old code not yet updated to the java.time types, you can convert between the legacy classes and java.time. Look to new methods add to the oldclasses.
最好避免麻烦的旧遗留日期时间类。但是,如果您必须与尚未更新为 java.time 类型的旧代码进行交互,则可以在遗留类和 java.time 之间进行转换。寻找添加到旧类的新方法。
A java.util.Date
is a moment on the timeline in UTC. So we need to extract an Instant
from our ZonedDateTime
. The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
Ajava.util.Date
是 UTC 时间线上的一个时刻。所以我们需要Instant
从我们的ZonedDateTime
. 该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Instant instant = zdt.toInstant() ;
java.util.Date d = java.util.Date.from( instant ) ; // Convert from java.time to legacy class.
Going the other direction.
走向另一个方向。
Instant instant = d.toInstant() ; // Convert from legacy class to java.time class.
ZonedDateTime zdt = instant.atZone( z ) ; // Adjust from UTC into a particular time zone.
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现 java.time 类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。