解析DateFormat时的Java时区

时间:2010-12-27 23:44:00

标签: java datetime timezone date-format iso8601

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

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服务器上究竟会改变这样的设置,以便我们在将来意识到这些变化?

8 个答案:

答案 0 :(得分:10)

TL;博士

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

ISO 8601

输入字符串格式在Mr. Jonathan Leffler标准中定义,该标准是一系列日期时间格式。

避免旧的日期时间类

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

使用java.time

您的输入字符串以ISO 8601结尾。所以我们解析为offset-from-UTC对象。

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

Instant

如果您希望在UTC时间轴上查看此日期时间值,请提取Instant instant = odt.toInstant();

ZoneId

时区是偏移量加上用于处理夏令时(DST)等异常的一组规则。如果您考虑了时区,请应用ZonedDateTime来获取ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = odt.atZoneSameInstant( z ); // Same moment on the timeline, but viewed through a different wall-clock time. 个对象。时间轴上的相同时刻,但通过不同的OffsetDateTime进行查看。

java.sql.*

关于 java.time

wall-clock time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacyjava.util.Date和& Calendar

现在位于SimpleDateFormatJoda-Time项目建议迁移到maintenance mode类。

要了解详情,请参阅java.time。并搜索Stack Overflow以获取许多示例和解释。规范是Oracle Tutorial

您可以直接与数据库交换 java.time 对象。使用符合JSR 310或更高版本的JDBC driver。不需要字符串,不需要li { list-style-type: none; position: relative; } li div { font-size: 60vw; position: absolute; text-align: center; top: 7vw; left: -3vw; width: 100%; }类。

从哪里获取java.time类?

  • JDBC 4.2Java SE 8以及之后
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小功能和修复。
  • Java SE 9Java SE 6
    • 大部分java.time功能都被反向移植到Java 6& 7 {in Java SE 7
  • ThreeTen-Backport
    • 更新版本的Android捆绑java.time类的实现。
    • 对于早期的Android,Android项目会调整 ThreeTen-Backport (如上所述)。见ThreeTenABP

How to use ThreeTenABP…项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如ThreeTen-ExtraIntervalYearWeekYearQuarter

答案 1 :(得分:4)

另一个应用程序使用ISO 8601 dateTime格式。我假设其他应用程序发送的XML响应符合XML Schema的dateTime类型,即ISO 8601.现在,已知的事情是DateFormat无法解析此格式。您必须使用其他库,如joda-time(joda-time是赢家)或其他响应中指定的FastDateFormat。看看这篇文章Converting ISO 8601-compliant String to java.util.Date

答案 2 :(得分:1)

如果你想使用直接JDK解析它,我相信它应该可以使用JAXB工具来解析,请参阅DatatypeFactory.newXMLGregorianCalendarDatatypeConverter.parseDateTime

答案 3 :(得分:1)

使用JodaTime

作为@ Pangea建议使用JodaTime的更具体的例子,这是你可以使用的:

String timestamp = "2012-09-17T04:11:46Z";

DateTime date = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

这正确识别UTC时区。我没有在字符串时间戳中用毫秒来尝试它,但我相信它也能正常工作。

希望能帮助他人。

JP

答案 4 :(得分:0)

问题应该是requiredTimeStamp的来源和格式。是由用户输入,还是从其他程序读取?哪个组件在String表示中创建日期?

格式“2010-12-27T10:50:44.000-08:00”看起来像标准格式ISO-8601 应该可以使用模式yyyy-MM-dd'T'HH:mm:ss.SSSZ

进行解析

不确定哪些设置会影响这一点,但有一个Oracle FAQ about Java TimeZones。 它可能是user.timezone系统属性或RHEL中的/etc/localtime符号链接。

答案 5 :(得分:0)

尝试将其更改为小写z。

z处理大多数常见的通用时区语法,而Z使用更严格的RFC 822时区4位数。

虽然它记录了两者都应解析“常规时区设置”,但它可能会对您的情况产生影响。

答案 6 :(得分:0)

SimpleDateFormat仅接受-0800GMT-08:00作为时区。

似乎无法使用SimpleDateFormat解析ISO 8601格式。也许你应该看看Apache Commons LangFastDateFormat。它与SimpleDateFormat兼容,但接受应该解析所需时区格式的时区的ZZ模式。 DateFormatUtils包含一些示例常量,看起来像您需要的模式,只是没有毫秒(例如ISO_DATETIME_TIME_ZONE_FORMAT)。

答案 7 :(得分:0)

如果仍在寻找答案,这对我有用

我的输入: 2020-12-08T10:36:53.939 + 05:30
我的输出: Tue Dec 08 10:36:53 IST 2020

您可以将此日期转换为所需的任何格式!

private static Date convertDate(String input) {
    Date newDate = null;
    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        newDate=dateFormat.parse(input);  
    } catch (Exception e) {
        e.printStackTrace();
    }
    return newDate;
}