使用冒号分隔符格式化 ISO 8601 日期

Formatting ISO 8601 date with a colon seperator

我正在尝试将以毫秒为单位的日期转换为以下 ISO 8601 格式:

但我使用 SimpleDateFormat 得到以下结果:

    /**
     * It converts the time from long to the ISO format
     * 
     * @param timestampMillis
     * @return isoDate
     */
    public String convertTimeMillisToISO8601(String timestampMillis)
    {
        long timeInLong= Long.parseLong(timestampMillis);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        String isoDate = df.format(new java.util.Date(timeInLong));
        return isoDate;
    }

输出:

"ts":"2015-06-18T09:56:21+0000"

我知道我可以使用子字符串来附加额外的冒号,但有没有更好的方法呢?

对于 Java 7 及更高版本,您可以在日期格式字符串中使用 XXX(ISO 8601 时区)。根据the documentationX的结果可以是:

X    => -08
XX   => -0800
XXX  => -08:00

但对于所有这些,它还不如 return Z!

对于 Java 6 及更早版本,没有 X (J6 doc),并且由于 X 的结果可能会或可能不会如您所愿,我强烈建议您自己插入那个冒号。

你能用Java8吗?

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ssXXX");
System.out.println(formatter.format(ZonedDateTime.now()));

2015-04-15T17:24:19+09:00

你总是可以:

new StringBuilder(
      new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
      .format(date))
    .insert(22,':')
    .toString();

对于 Java 8,如果您使用标准 ISO_DATE_* 格式模式之一,那么当偏移量为 +00 时,output 格式的字符串将被截断:00(UTC 通常只是附加 Z)。

OffsetDateTime utcWithFractionOfSecond = ZonedDateTime.parse("2018-01-10T12:00:00.000000+00:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);

utcWithFractionOfSecond.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);     // 2018-01-10T12:00:00Z ... not what you want!

我找到的唯一解决方案是使用 outputPattern(如下所示),它使用 小写 `xxx' 来确保时区偏移量中包含一个冒号.

为了完整起见,我已经包含了一个每秒派系的示例(您可以在您的案例中删除 SSSSSS

DateTimeFormatter inputPattern = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx");

OffsetDateTime utcWithFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00.000000+00:00", inputPattern);
OffsetDateTime utcNoFractionOfSecond = OffsetDateTime.parse("2018-01-10T12:00:00+00:00", inputPattern);
OffsetDateTime utcWithZ = OffsetDateTime.parse("2018-01-10T12:00:00Z", inputPattern);
OffsetDateTime utcPlus3Hours = OffsetDateTime.parse("2018-01-10T12:00:00.000000+03:00", inputPattern);|

utcWithFractionOfSecond.format(outputPattern );     // 2018-01-10T12:00:00.000000+00:00
utcNoFractionOfSecond.format(outputPattern);        // 2018-01-10T12:00:00.000000+00:00
utcWithZ.format(outputPattern);                     // 2018-01-10T12:00:00.000000+00:00
utcPlus3Hours.format(outputPattern);                // 2018-01-10T12:00:00.000000+03:00

在这些示例中,我仅使用 ISO_OFFSET_DATE_TIME 来创建测试用例的输入值。在所有情况下,outputPattern yyyy-MM-dd'T'HH:mm:ss.SSSSSSxxx 控制如何在生成的格式化字符串的时区部分包含冒号字符。

请注意,如果您的输入数据包含像 [Europe/London] 这样的区域 ID,那么您将使用 ZonedDateTime 而不是 OffsetDateTime

创建您的输入数据

tl;博士

OffsetDateTime.parse( "2014-06-18T09:56:21+00:00" )

2014-06-18T09:56:21Z

详情

其他一些答案很接近,正确地使用现代 java.time classes 取代了可怕的旧遗产 classes ( DateCalendarSimpleDateFormat)。但他们不是太努力了,就是选错了class.

ISO 8601

您的格式是标准 ISO 8601 格式。 java.time classes 在 parsing/generating 文本表示其日期时间值时默认使用这些标准格式。所以你根本不需要指定任何格式模式。默认情况下工作。

OffsetDateTime

您的输入表明 offset-from-UTC of zero hours and zero minutes. So we should use the OffsetDateTime class。

String input = "2014-06-18T09:56:21+00:00";
OffsetDateTime odt = OffsetDateTime.parse( input );

祖鲁时代

我们只需调用 toString 即可生成标准 ISO 8601 格式的字符串。末尾的Z表示UTC,发音为“Zulu”。

odt.toString(): 2014-06-18T09:56:21Z

ZonedDateTime

如果您输入的是时区,而不仅仅是偏移量,我们会使用 ZonedDateTime class。偏移量只是小时数、分钟数和秒数——仅此而已。时区 。时区是特定地区人们使用的偏移量的过去、现在和未来变化的历史。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

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

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.