【问题标题】:Convert java.util.Date with custom time zone to UTC [duplicate]将具有自定义时区的 java.util.Date 转换为 UTC [重复]
【发布时间】:2020-07-07 02:51:35
【问题描述】:

我有一个java.util.Date 对象。当我将其格式化为String 时,使用:

String timeString = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss-Z").format(time);

我明白了:

2020-03-26-14:40:55-+0200

所以,不知何故,我有正确的时区(但我可以有任何时区,不仅仅是+2),这很好。

我想将此日期转换为 UTC,然后将其转换为 String。如果我向客户端发送一个带有日期的对象,那么Jackson 会自动将其转换为UTC。但我想手动执行此操作。

我该怎么做?

【问题讨论】:

  • 投什么反对票?
  • 我建议你不要使用SimpleDateFormatDate。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用例如OffsetDateTimeDateTimeFormatter,两者都来自java.time, the modern Java date and time API
  • 这是一种特殊的格式。你不想在ISO 8601 format 中有一个字符串吗?
  • 在偏移前插入连字符很奇怪,而且非常混乱。我强烈建议您坚持使用 ISO 8601 标准格式。

标签: java datetime jackson datetime-format utc


【解决方案1】:

不建议再使用java.util 进行日期时间操作,尤其是不用于时区或偏移量转换...

改为使用java.time:

public static void main(String[] args) {
    // the String (with a strange formatting) to be parsed
    String datetime = "2020-03-26-14:40:55-+0200";
    // parse it to an OffsetDateTime
    OffsetDateTime odt = OffsetDateTime.parse(datetime,
                                    // using a formatter for this specific pattern
                                    DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-x"));
    // print the parsing result
    System.out.println(odt);
    // then convert it to UTC (keeping the moment & adjusting the offset)
    OffsetDateTime odtUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
    // print the conversion result
    System.out.println(odtUtc);
}

为您提供以下输出

2020-03-26T14:40:55+02:00
2020-03-26T12:40:55Z

【讨论】:

  • 谢谢,我知道java.util.Date 已被弃用。但我现在真的需要使用它。
  • @don-prog 如果你想要得到的只是一个String,你能告诉我为什么你必须使用它吗?
  • 因为我的代码到处都有java.util.Date 作为字段。不知道迁移需要付出多少努力
  • @don-prog 取决于... 您可以尝试使用兼容性方法(我不能真正推荐)或重构您的整个代码。如果太费劲,就只好坚持麻烦又容易出错的java.util.Date,你的决定……There`s more than a single reason for a new datetime API
【解决方案2】:

java.time

我知道您有一个 java.util.Date 类型的字段,您现在无法更改。对于Date 上的任何操作,您仍应首先将其转换为现代Instant,然后从那里进行进一步的工作。要将其转换为 UTC 字符串,您可以使用非常简单的方法:

    String timeString = yourJavaUtilDate.toInstant().toString();
    System.out.println(timeString);

示例输出:

2020-03-26T12:40:55Z

虽然Instant 是一个没有时区或偏移的时间点,但就像Date 一样,Instant.toString() 以 ISO 8601 格式生成 UTC 字符串,我觉得这非常好。如果您想要问题中提到的特殊格式(您必须有非常特殊的原因):

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-Z");
    String timeString = yourJavaUtilDate.toInstant()
            .atOffset(ZoneOffset.UTC)
            .format(formatter);

2020-03-26-12:40:55-+0000

来自SimpleDateFormat 的格式模式字符串也适用于现代DateTimeFormatter。并非总是如此,两者的格式模式字母集之间存在差异,只有许多字母具有相同或相似的含义。

我自己正在使用一个非常古老的代码库,多年来它已经获得了过时和现代日期和时间类的混乱混合。所以我们不断在DateLocalDateOffsetDateTimeXMLGregorianCalendar 和许多其他类之间来回转换,这远非理想,而且还需要几年时间才能到达最佳位置我们将只使用现代类。

链接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 2020-03-21
    • 2014-10-05
    • 2012-08-21
    • 2020-06-16
    • 2016-10-16
    相关资源
    最近更新 更多