0

我正在尝试检查日期是否已超过一天。

我在解析字符串时得到了这些错误。

java.lang.IllegalArgumentException: Pattern ends with an incomplete string literal: uuuu-MM-dd'T'HH:mm:ss'Z
org.threeten.bp.format.DateTimeParseException: Text '2020-04-04T07:05:57+00:00' could not be parsed, unparsed text found at index 19

我的数据示例在这里:

val lastDate = "2020-04-04T07:05:57+00:00"
val serverFormat = "uuuu-MM-dd'T'HH:mm:ss'Z"
val serverFormatter =
        DateTimeFormatter
            .ofPattern(serverFormat)
val serverDateTime =
        LocalDateTime
            .parse(
                lastDate,
                serverFormatter
            )
            .atZone(ZoneId.of("GMT"))
val clientDateTime =
        serverDateTime
            .withZoneSameInstant(ZoneId.systemDefault())

val timeDiff =
        ChronoUnit.DAYS.between(
            serverDateTime,
            clientDateTime

我试过这些:

uuuu-MM-dd\'T\'HH:mm:ss\'Z
yyyy-MM-dd\'T\'HH:mm:ss\'Z
uuuu-MM-dd\'T\'HH:mm:ss
uuuu-MM-dd'T'HH:mm:ss'Z
yyyy-MM-dd'T'HH:mm:ss'Z
uuuu-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd'T'hh:mm:ss'Z
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss

他们都没有工作......正确的方法是什么?

4

1 回答 1

2

您不需要任何显式格式化程序。在 Java 中(因为这是我能写的):

    String lastDate = "2020-04-04T07:05:57+00:00";
    OffsetDateTime serverDateTime = OffsetDateTime.parse(lastDate);
    ZonedDateTime clientDateTime
            = serverDateTime.atZoneSameInstant(ZoneId.systemDefault());

    System.out.println("serverDateTime: " + serverDateTime);
    System.out.println("clientDateTime: " + clientDateTime);

在我的时区输出:

serverDateTime: 2020-04-04T07:05:57Z
clientDateTime: 2020-04-04T09:05:57+02:00[Europe/Copenhagen]

来自服务器的字符串格式为 ISO 8601。java.time 类将最常见的 ISO 8601 变体解析为默认值,也就是说,没有指定任何格式化程序。

由于来自您服务器的字符串具有 UTC 偏移量,+00:00,并且没有像亚洲/首尔这样的时区,OffsetDateTime因此是使用它的最佳和最正确的时间。另一方面,客户端时间有时区,所以ZonedDateTime在这里很好。

由于服务器和客户端时间表示相同的时间,因此差异将始终为零:

    Duration difference = Duration.between(serverDateTime, clientDateTime);
    System.out.println(difference);
PT0S

读取为 0 秒的时间段(这也是 ISO 8601 格式)。

如果您想知道当前时间和服务器时间之间的差异,请使用now()

    Duration difference = Duration.between(serverDateTime, OffsetDateTime.now());
    System.out.println(difference);

你的代码出了什么问题?

首先,字符串中的 UTC 偏移量是+00:00. 一个格式模式字母Z和文字Z都不会匹配这个。所以不要这样尝试。其次,永远不要在格式模式字符串中给出Z用单引号括起来的文字。当 aZ作为偏移量出现时,这很常见,您需要将其解析为偏移量,而不是文字。第三,格式模式字符串中的文字文本需要在其前后有一个单引号和一个单引号。T您在中间正确地做这件事。如果您不想Z成为文字,请不要在其前面加上单引号。如果你的意思是字面意思——就像我说的那样,别这样。

链接

于 2020-05-05T14:20:07.283 回答