首页 > 解决方案 > DateTimeFormatter 和 ISO 8601 字符串

问题描述

我正在使用一个 RESTful api,它以 ISO-8601 格式返回带有偏移量的日期,一个示例如下所示......

 2019-12-30T00:00:00.000+00:00

我正在使用以下方法将日期字符串转换为传递的格式,它使用 DateTimeFormatter.ISO_DATE_TIME,我根据来自 oracle 的文档选择了这个,该文档声明“这将返回一个能够格式化和解析 ISO-8601 扩展的不可变格式化程序本地或偏移日期时间格式"

 public static String formatISODateTime(String isoString, String format) {

    LocalDate date = null;
    String returnDate = null;
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;

    try{
        date = LocalDate.parse(isoString, dateTimeFormatter);
        returnDate = date.format(DateTimeFormatter.ofPattern(format));
    } catch(DateTimeParseException e) {         
        // do something
    } catch(DateTimeException e) {          
        // do something
    }

    return returnDate;
}

下面是这个方法的简单测试...

 public static void main(String[] args) {

    System.out.println(BaseConverter.formatISODateTime("2019-12-27T00:00:00.000+00:00", "MM/dd/yyyy"));
    System.out.println(BaseConverter.formatISODateTime("2019-12-27T00:00:00.000+18:00", "MM/dd/yyyy"));
    System.out.println(BaseConverter.formatISODateTime("2019-12-27T00:00:00.000-18:00", "MM/dd/yyyy"));
}

这是输出...

 12/27/2019
 12/27/2019
 12/27/2019

我很难理解为什么偏移量(-/+ 18)不会产生不同的日期?

标签: javatime

解决方案


您正在解析为本地日期。

尽管沿时间线表示不同的瞬间(由于偏移),但在当地情况下,中国的 12 月 27 日与委内瑞拉的 12 月 27 日相同。也就是说,当你实例化LocalDates 时,信息就不可逆转地丢失了。

如果您想打印不同的日期,您可能希望转换为 UTC。

首先,您需要解析成一个同时保留时间和区域信息的结构(ZonedDateTime这样做),然后您可以手动转换为 UTC。

public static String formatISODateTime(String isoString, String format) {

    ZonedDateTime date = null;
    String returnDate = null;
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;

    try {
        date = ZonedDateTime.parse(isoString, dateTimeFormatter).withZoneSameInstant(ZoneOffset.UTC);
        returnDate = date.format(DateTimeFormatter.ofPattern(format));
    } catch(DateTimeParseException e) {
        // do something
    } catch(DateTimeException e) {
        // do something
    }

    return returnDate;
}

这打印

12/27/2019
12/26/2019
12/27/2019

推荐阅读