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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:35:03  来源:igfitidea点击:

Java - Unparseable date

javasimpledateformat

提问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 Localeto 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 LocalDateTimewhich 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.

输入字符串缺少时区或偏移量。我们解析为LocalDateTimewhich不是时间轴上的时刻,只是对可能时刻的模糊概念。就像说“圣诞节从 2017 年 12 月 25 日午夜开始”一样,除非您将其置于特定时区的上下文中,否则这没有任何意义。新西兰奥克兰的圣诞节比法国巴黎的圣诞节要早得多,而魁北克蒙特利尔的圣诞节则要晚得多。

If you know the intended time zone, assign a ZoneIdto 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.Dateis a moment on the timeline in UTC. So we need to extract an Instantfrom our ZonedDateTime. The Instantclass 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 类?

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 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多