Java - 无法解析的日期

Amo*_*tir 15 java simpledateformat

我试图解析一个约会,但我奇怪地得到一个例外.

这是代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

例外是:

java.text.ParseException:无法解析的日期:"Wed,09 Feb 2011 12:34:27",位于DateTest.main的java.text.DateFormat.parse(DateFormat.java:337)(DateTest.java:17)

我已阅读文档,我认为我的模式是正确的.所以我不明白......

任何的想法?

谢谢!

a_h*_*ame 37

这可能是因为您的计算机上的默认语言环境不是英语.

你应该使用:

new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH);
Run Code Online (Sandbox Code Playgroud)

代替.


Bas*_*que 5

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()

)
Run Code Online (Sandbox Code Playgroud)

细节

问题和其他答案都使用过时的麻烦的旧日期时间类,这些类现在是遗留的,由 java.time 类取代。

使用 java.time

输入字符串缺少时区或UTC 偏移量的任何指示。所以我们解析为OffsetDateTime.

指定 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 ) ;
Run Code Online (Sandbox Code Playgroud)

ldt.toString(): 2011-02-09T12:34:27

时区

问题和其他答案都忽略了时区的关键问题。

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

如果您知道预期的时区,请分配 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.
Run Code Online (Sandbox Code Playgroud)

转换

最好避免麻烦的旧遗留日期时间类。但是,如果您必须与尚未更新为 java.time 类型的旧代码进行交互,则可以在遗留类和 java.time 之间进行转换。寻找添加到类的新方法。

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.
Run Code Online (Sandbox Code Playgroud)

走向另一个方向。

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.
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获得 java.time 类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多