Java - 不可解析的日期tl;博士详使用 java.time时区转换关于 java.time

2022-09-02 19:33:46

我正在尝试解析日期,但奇怪的是,我得到了一个异常。

这是代码:

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

例外情况是:

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)

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

有什么想法吗?

谢谢!


答案 1

这可能是因为计算机上的默认区域设置不是英语。

您应该使用:

new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH);

相反。


答案 2

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

)

Question 和其他 Answer 都使用过时的麻烦的旧日期时间类,这些类现在是遗留的,被 java.time 类所取代。

使用 java.time

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

指定区域设置以确定 (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

时区

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

输入字符串缺少时区或偏移量。我们解析为一个不是时间轴上的时刻,只是一个关于可能时刻的模糊想法。就像说“圣诞节从2017年12月25日午夜开始”一样,在你把它放在特定时区的上下文中之前,这没有任何意义。圣诞节在新西兰奥克兰比在法国巴黎来得早得多,在魁北克蒙特利尔也要晚得多。LocalDateTime

如果您知道预期的时区,请指定 一个以生成 .ZoneIdZonedDateTime

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ldt.atZone( z ); // Assigning a time zone to determine an actual moment on the timeline.

转换

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

A 是 UTC 时间轴上的一个时刻。因此,我们需要从我们的 .Instant 类以 UTC 格式表示时间轴上的某个时刻,分辨率为纳秒(最多九 (9) 位小数)。java.util.DateInstantZonedDateTime

Instant instant = zdt.toInstant() ;
java.util.Date d = java.util.Date.from( instant ) ;  // Convert from java.time to legacy class.

朝另一个方向走。

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.

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

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

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


推荐