我正在检查日期是否超过一天。
当它解析字符串时,我得到了这些错误。
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
他们都不起作用。。。正确的方法是什么?
您不需要任何显式格式化程序。在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的类将最常见的ISO8601变体解析为默认值,也就是说,不指定任何格式化程序。
由于来自服务器的字符串具有UTC偏移量+000: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
都不会与此匹配。所以不要这么做。其次,never在格式模式字符串中,将Z
作为单引号括起来的文字。当Z
显示为偏移量时(这很常见(,您需要将其解析为偏移量,而不是文字。第三,格式模式字符串中的文本需要在前面有一个单引号,在后面有一个双引号。对于在中间的T
,这样做是正确的。如果你不是说Z
是字面意思,就不要在它前面加一句引号。如果你确实是说它是字面意思——正如我所说,就是不要。
链接
- 维基百科文章:ISO 8601
- 一个参数
OffsetDateTime.parse()
的文档