解析日期格式时的 Java 时区tl;博士国际标准化组织 ISO 8601避免旧的日期时间类使用 java.time关于 java.time

2022-09-04 06:03:57

我有解析日期的代码,如下所示:

String ALT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
SimpleDateFormat sdf = new SimpleDateFormat(
                    ALT_DATE_TIME_FORMAT);
Date date = sdf.parse(requiredTimeStamp);

它工作正常,突然间,它停止工作了。事实证明,管理员在服务器上进行了一些配置更改,并且日期当前返回为“2010-12-27T10:50:44.000-08:00”,上述模式无法解析。我有两个问题:

第一种是哪种模式将以上述格式解析JVM返回的日期(具体来说,只是“-08:00”作为时区)?其次,究竟在哪里可以更改Linux RHEL 5服务器上的此类设置,以便我们将来了解此类更改?


答案 1

tl;博士

OffsetDateTime.parse( "2010-12-27T10:50:44.000-08:00" )

国际标准化组织 ISO 8601

输入字符串格式在 ISO 8601 标准(一系列日期时间格式)中定义。

避免旧的日期时间类

问题和其他答案使用与Java的最早版本捆绑在一起的旧过时的日期时间类。避免它们。现在被java.time类所取代。

使用 java.time

输入字符串以 UTC 偏移量结尾。因此,我们解析为 OffsetDateTime 对象。

java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。因此,无需指定格式设置模式。

OffsetDateTime odt = OffsetDateTime.parse( "2010-12-27T10:50:44.000-08:00" );

如果要将此日期时间值作为时间轴上的某个时刻(UTC 格式)进行查看,请提取 .Instant

Instant instant = odt.toInstant();

时区是偏移量加上一组用于处理异常(如夏令时 (DST))的规则。如果您心中包含时区,请应用 a 来获取对象。时间轴上的相同时刻,但通过不同的挂钟时间查看。ZoneIdZonedDateTime

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );  // Same moment on the timeline, but viewed through a different wall-clock time.


关于 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


答案 2

另一个应用程序使用 ISO 8601 日期时间格式。我假设另一个应用程序正在向您发送符合XML架构的dateTime类型(即ISO 8601)的XML响应。现在,众所周知,DateFormat无法解析此格式。您必须使用其他库,例如joda-time(joda-time是赢家)或FastDateFormat,如其他响应中指定的那样。看看这篇文章 将符合ISO 8601的字符串转换为java.util.Date