如何将日期字符串转换为 UTC 日期对象?

Posted

技术标签:

【中文标题】如何将日期字符串转换为 UTC 日期对象?【英文标题】:How to convert Date string into UTC Date object? 【发布时间】:2022-01-11 00:56:52 【问题描述】:

我正在学习 Java,遇到了这个问题。我有一个给定格式的日期字符串。

String dbTime = "01/01/1998 12:30:00";
final String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss";

现在我想初始化/创建一个 UTC 时区的 Date 对象。 为此,我尝试了以下代码

    SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
    TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
    sdfAmerica.setTimeZone(utcTimeZone);

    String sDateInAmerica = sdfAmerica.format(date); // Convert to String first
    Date dateInAmerica = new Date();
    try 
        dateInAmerica = formatter.parse(sDateInAmerica); // Create a new Date object
     catch (ParseException e) 
        e.printStackTrace();
    

这会将时间转换为 UTC,而不是仅仅创建一个日期对象。

01/02/1998 23:00:00

现在我很困惑哪种是转换时间的正确方法。 我有时间使用字符串格式,我必须将其转换为不同的格式,主要是 UTC 到 PST 或 PST 到 UTC。

经过一番研究,我找到了this 教程但无法获得预期的输出。

【问题讨论】:

你在 2021 年学习 Java 并尝试使用SimpleDateFormat?! 停下!!马上! 我们其他人很多年前就停止使用那个类了,因为它太麻烦了。因为它的替代品 DateTimeZone 在 7 年半前的 2014 年初推出了现代 Java 日期和时间 API java.time。 另外,Date 对象没有时区,因此不能(或不是)UTC。现代的OffsetDateTimeZonedDateTime 可以是un UTC。见the good answer by Roland Kreuzer。 【参考方案1】:

java.util.Date 类不是最好的开始。虽然从外面看起来像是一个完整的日期,但它实际上只代表一个时间戳,没有存储实际的时区信息。

在 Java 8 及更高版本上,我建议坚持使用设计更好的 java.time.* 类。

    String dbTime = "01/01/1998 12:30:00";
    String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss";

    // parsed date time without timezone information
    LocalDateTime localDateTime = LocalDateTime.parse(dbTime, DateTimeFormatter.ofPattern(DATE_FORMAT));

    // local date time at your system's default time zone
    ZonedDateTime systemZoneDateTime = localDateTime.atZone(ZoneId.systemDefault());

    // value converted to other timezone while keeping the point in time
    ZonedDateTime utcDateTime = systemZoneDateTime.withZoneSameInstant(ZoneId.of("UTC"));

    // timestamp of the original value represented in UTC
    Instant utcTimestamp = systemZoneDateTime.toInstant();


    System.out.println(utcDateTime);
    System.out.println(utcTimestamp);

从名称可以看出,不同的日期用例有不同的类。

例如 java.time.LocalDateTime 仅表示没有特定时区上下文的日期和时间,因此可用于直接解析您的字符串值。

要转换时区,首先必须转换为 ZonedDateTime,它接受日期、时间和时区。我已经在“systemDefault”上初始化了示例,因为在大多数较小的应用程序上,您可以使用 JVM 和操作系统的默认值来假设当前时区。 如果您想确保该值被解释为太平洋时间,也可以直接使用 ZoneId.of("America/Los_Angeles")。

此值可以转换为另一个时区的另一个 ZonedDateTime,例如世界标准时间。

特别是对于 UTC,您还可以使用 Instant 类,它仅表示 UTC 时间戳,也可以用作大多数其他类型的基础

【讨论】:

感谢您的精彩解释,并感谢您带领 OP 和其他所有人走上改进现代方法来做这些事情 (+1)。

以上是关于如何将日期字符串转换为 UTC 日期对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UTC 日期字符串转换为本地时间 (systemTimeZone)

如何将 UTC 日期时间字符串转换为用户的当前时区?

如何将日期正确转换为 UTC,然后再转换回来?

如何将 UTC 时间转换为本地时间

通过 Ajax 将 Javascript 日期转换为 C#

将 UTC 日期时间字符串转换为本地日期时间