接收日期,包括时区偏移量作为字符串,并使用该时区转换为不同的格式

Receive Date including timezone offset as String and convert to a different format using that timezone

我从我的客户那里收到了一个类似这种格式的字符串

yyyy-MM-dd'T'HH:mm:ss.SSSXXX:

2021-02-04T15:31:22.265-05:00
2021-02-04T15:31:22.265+00:00
2021-02-04T15:31:22.265-06:00

我需要将它们转换为新格式:

MMMM dd, yyyy - HH:mm a z (where z is the three character abbreviation for the timezone. Ex. EST)

February 02, 2021 - 15:31 PM EST
February 02, 2021 - 15:31 PM UTC
February 02, 2021 - 15:31 PM CST

通常我会做这样的事情:

SimpleDateFormat inDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
        SimpleDateFormat outDateFormat = new SimpleDateFormat("MMMM dd, yyyy - HH:mm a z")
        Date date = inDateFormat.parse("2021-02-04T15:31:22.265-05:00");
        String convertedTime = outDateFormat.format(date) // February 02, 2021 - 15:31 PM EST

但我后来意识到它只是在打印 EST,因为那是我所在的地方。但是,如果用户在另一个时区并使用它,它将成为他们的时间,但 EST 仍将结束。例如,如果他们发送 2021-02-04T15:31:22.265+00:00,那么它将 return 2021 年 2 月 2 日 - 15:31 PM EST,这对他们来说是过去 5 小时.

那么我如何获取包含偏移量的字符串并将其简单地转换为具有相同偏移量的不同格式的字符串? 我希望来自UTC 发送 2021-02-04T15:31:22.265+00:00 为 2021 年 2 月 2 日 - 15:31 PM UTC

您可以从时区 ID 导出时区偏移量,但反之则不行,即您不能使用时区偏移量导出时区 ID;因为相同的时区偏移量可适用于许多时区 ID,例如

以下代码绝对有效

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Paris]");
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MMMM dd, uuuu - HH:mm a XXX");
        System.out.println(zdt.format(dtfOutput));
    }
}

输出:

December 03, 2007 - 10:15 am +01:00

而以下代码将抛出异常:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2021-02-04T15:31:22.265-05:00");
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MMMM dd, uuuu - HH:mm a z");
        System.out.println(odt.format(dtfOutput));
    }
}

输出:

Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2021-02-04T15:31:22.265-05:00
    at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
    at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4083)
    at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2343)
    at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1848)
    at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1822)
    at java.base/java.time.OffsetDateTime.format(OffsetDateTime.java:1681)
    at Main.main(Main.java:8)

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

请注意 java.util 的日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API.

  • 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它向后移植了大部分 java.time Java 6 和 7 的功能。
  • 如果您正在为 Android 项目工作,并且您的 Android API 水平仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and