【问题标题】:How to get LocalDate(yyyy-MM-dd) format from given OffsetDatetime and return as OffsetDatetime without zone offset?如何从给定的 OffsetDatetime 获取 LocalDate(yyyy-MM-dd) 格式并返回为 OffsetDatetime 而没有区域偏移?
【发布时间】:2021-06-04 18:46:05
【问题描述】:

我目前收到 java.time.OffsetDateTime 的偏移量如下:

2021-06-05T18:29:31Z

2021-06-05T18:29:38.723Z

是否可以将其转换为 LocalDate 格式(yyyy-MM-dd)并返回为 java.time.OffsetDateTime

我用 DateTimeFormatter 尝试了以下操作,但没有成功。

        String offsetDateTimeString = offsetDateTime.toString();

        DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd")
                .toFormatter();
        return OffsetDateTime.parse(offsetDateTimeString, dateTimeFormatter)

如果无法转换为 yyyy-MM-dd 格式,则也无法转换为没有区域偏移的格式。

        String offsetDateTimeString = offsetDateTime.toString();
        DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
                .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
                .toFormatter();

OffsetDateTime offsetDateTime = OffsetDateTime.parse(offsetDateTimeString, dateTimeFormatter);

运行此代码时我得到DateTimeParseException

java.time.format.DateTimeParseException: Text '2021-06-05T18:39:51.578Z' could not be parsed, unparsed text found at index 19

我需要在 OffsetDateTime 中以“yyyy-MM-dd”或“yyyy-MM-dd'T'HH:mm:ss”格式返回给定日期。

【问题讨论】:

  • 当您对时间或偏移量都不感兴趣时​​,为什么您将 OffsetDateTime 作为返回类型而不是 LocalDate?
  • 我只需要传递 java.time.OffsetDateTime 中的值。这是给定的要求。
  • 那么你还需要有一个时间部分和一个偏移量,这就是 OffsetDateTime 需要的。您可以更改时间或偏移量,但不能将其删除。
  • OffsetDateTime始终具有日期、时间和偏移量。它的名字是:偏移日期时间。它不能没有这三个部分之一。如果你想要一个没有时间或偏移量的日期,你需要使用LocalDate,并且有一个没有偏移量的日期和时间,你需要使用LocalDateTime。 --- 但是,您可以在 Time 和 Offset 值为 0 时创建 OffsetDateTime。实际上,Z 偏移量已经为 0,因此您只需将时间也更改为 0
  • 仅供参考:显示值时,您始终可以选择应用自定义 DateTimeFormatter 仅显示日期部分:@987654332 @

标签: java date java-time


【解决方案1】:

不,你不能有一个没有偏移量的OffsetDateTime,也不能有一个没有时间的OffsetDateTime。顾名思义,OffsetDateTime 必然包含日期、时间和与 UTC 或 GMT 的偏移量。你问的有点像要求一个没有减号的负数或一个值为t而不是trueboolean

OffsetDateTime 也不能有格式。您可以使用任何您喜欢的格式,但不能在日期时间对象中(也不能在LocalDate 中),只能在String 中。当你打印你的OffsetDateTime 时你看到的是调用它的toString 方法的结果。该方法的文档说:

输出将是以下 ISO-8601 格式之一:

  • uuuu-MM-dd'T'HH:mmXXXXX
  • uuuu-MM-dd'T'HH:mm:ssXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXXXX
  • uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX

使用的格式将是输出完整值的最短格式 省略部分被暗示为零的时间。

您注意到所有可能的格式都至少包括小时和分钟以及偏移量。

那么该怎么做呢?两种建议,其中一种可能适用于您的情况:

  1. OffsetDateTime 设置为UTC 的一天开始时间。
  2. OffsetDateTime 设置为JVM 默认时区的一天的开始。

在代码中:以 UTC 表示的一天的开始时间(总是 00:00):

    // Example received value
    OffsetDateTime offsetDateTime = OffsetDateTime.of(
            2021, 6, 5, 18, 29, 38, 723_000_000, ZoneOffset.UTC);
    
    OffsetDateTime dateOnly = offsetDateTime
            .withOffsetSameInstant(ZoneOffset.UTC)
            .truncatedTo(ChronoUnit.DAYS);
    System.out.println(dateOnly);

输出:

2021-06-05T00:00Z

默认时区的一天开始时间(通常也是 00:00):

    OffsetDateTime dateOnly = offsetDateTime
            .atZoneSameInstant(ZoneId.systemDefault())
            .truncatedTo(ChronoUnit.DAYS)
            .toOffsetDateTime();

当我在亚洲/鄂木斯克时区运行时,输出是:

2021-06-06T00:00+06:00

链接

Documentation of OffsetDateTime.toString()

【讨论】:

    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 2017-02-03
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多