【问题标题】:Parsing ISO-8601 DateTime with offset with colon in Java在 Java 中使用带冒号的偏移量解析 ISO-8601 DateTime
【发布时间】:2013-04-26 13:01:27
【问题描述】:

我在 java 中解析日期时间时遇到问题,我有一个奇怪的日期时间格式。 如何在java中解析2013-04-03T17:04:39.9430000+03:00日期时间以在java中格式化dd.MM.yyyy HH:mm

【问题讨论】:

  • 解析从文本到非文本。你格式化从非文本到文本。听起来您需要两个 SimpleDateFormat 对象 - 一个用于解析,另一个用于格式化。试试这个,如果你没有成功,就用你的尝试编辑你的问题。
  • 仅供参考,输入字符串采用标准ISO 8601 格式。
  • @BasilBourque 感谢您的回复,“drewmoore”还在下面说明了该日期的格式。

标签: java datetime datetime-parsing


【解决方案1】:

有问题的“奇怪”格式是ISO-8601 - 它使用非常广泛。您可以使用SimpleDateFormat 以您喜欢的大多数方式重新格式化它:

SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
DateTime dtIn = inFormat.parse(dateString});  //where dateString is a date in ISO-8601 format
SimpleDateFormat outFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
String dtOut = outFormat.format(dtIn);
//parse it into a DateTime object if you need to interact with it as such

会给你你提到的格式。

【讨论】:

  • 奇怪的是,(Simple)DateFormat 没有为广泛使用的 ISO-8601 格式提供标准选项,而是要求开发人员滚动他们自己的格式字符串。可能是因为 ISO-8601 可以有很多不同的变体。
  • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle
  • 此答案未能解决问题中的微秒/纳秒。
【解决方案2】:

tl;博士

OffsetDateTime.parse( "2013-04-03T17:04:39.9430000+03:00" ).format( DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm" ) )

ISO 8601

正如其他人所说,您的格式一点也不奇怪。事实上,它是一种标准格式。该格式是ISO 8601 格式定义的集合之一。

微秒

秒的小数部分的这七个数字,.9430000,代表nanoseconds。与 Java 的最早版本 (java.util.Date/.Calendar/java.text.SimpleDateFormat) 捆绑在一起的旧日期时间类仅适用于 milliseconds(三位小数)。旧类无法处理您的此类输入值。

java.time

幸运的是,Java 现在有更新的日期时间类来取代那些旧类。新的在java.time 框架中。这些新类可以处理纳秒(最多九位小数),所以没有问题。

java.time 框架内置于 Java 8 及更高版本中。在JSR 310 中定义。大部分功能在ThreeTen-Backport 项目中向后移植到Java 6 和7,并在ThreeTenABP 项目中进一步适用于Android。

OffsetDateTime

OffsetDateTime 表示时间轴上带有offset-from-UTC 的时刻。您的输入字符串2013-04-03T17:04:39.9430000+03:00 的偏移量比UTC 早三个小时。

java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。所以不需要定义格式化模式。我们可以直接解析那个字符串。

OffsetDateTime odt = OffsetDateTime.parse( "2013-04-03T17:04:39.9430000+03:00" );

生成字符串

要生成相同样式的字符串表示,请调用其toString 方法。

为不同的格式定义格式模式。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd.MM.uuuu HH:mm" );
String output = odt.format( formatter );

时区

请注意,您的输入具有与 UTC 的偏移量,但不是真正的时区。时区是用于处理夏令时 (DST) 等异常情况的偏移量加上规则。对于真正的时区,请使用ZoneId 获取ZonedDateTime。在 Stack Overflow 上搜索许多示例。


关于java.time

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

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

  • OffsetDateTimeDateTimeFormatter 的导入是什么? Android Studio 找不到它们。
  • @MatthewDrill 查看最近添加的项目符号。
【解决方案3】:

请使用此方法在没有任何库的情况下解析 ISO8601 日期。 http://www.java2s.com/Code/Java/Data-Type/ISO8601dateparsingutility.htm

public static Date parseISO8601Date(String input ) throws java.text.ParseException {

    //NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
    //things a bit.  Before we go on we have to repair this.
    SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );

    //this is zero time so we need to add that TZ indicator for
    if ( input.endsWith( "Z" ) ) {
        input = input.substring( 0, input.length() - 1) + "GMT-00:00";
    } else {
        int inset = 6;

        String s0 = input.substring( 0, input.length() - inset );
        String s1 = input.substring( input.length() - inset, input.length() );

        input = s0 + "GMT" + s1;
    }

    return df.parse( input );

}

【讨论】:

    【解决方案4】:

    对于在 java 中处理日期和时间的严肃工作,我建议使用比 Calendar 更好的实现。我会使用Joda,你可以使用DateTimeFormatter

    【讨论】:

    • 我的回答太糟糕以至于无法投反对票吗?反对者对此有何评论?也许我可以改进。我真的认为 Joda 时间比标准的 java 日期/时间实现有很多优势。
    • 我不是反对者,我喜欢 JodaTime 并经常使用它,但对于 OP 想要做的事情来说,这不是必需的,因此并不是这个问题的真正相关答案.
    • 您没有真正回答 OP 的问题。他可能处于无法将外部库添加到他的项目的情况。我不是反对者,这只是我的看法。不过,您的答案仍然是正确的,只是不是 100% 对 OP 的回答。
    • 仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle
    猜你喜欢
    • 2018-03-11
    • 2020-05-10
    • 2017-09-07
    • 2021-10-19
    • 2019-04-08
    相关资源
    最近更新 更多