在Java中,如何获取时间戳为48962-08-06T23:16:59.000Z的即时对象
我有一个日期字符串,我想将其解析为即时在Java中,如何获取时间戳为48962-08-06T23:16:59.000Z的即时对象,java,datetime,java-8,Java,Datetime,Java 8,我有一个日期字符串,我想将其解析为即时 48962-08-06T23:16:59.000Z但无法执行,因为大多数标准DateTimeFormatter规则都不支持它 参考: 下面是我使用自定义格式化程序尝试执行的操作 DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendValue(YEAR, 5, 10, SignStyle.EXCEEDS_PAD) .ap
48962-08-06T23:16:59.000Z
但无法执行,因为大多数标准DateTimeFormatter规则都不支持它
参考:
下面是我使用自定义格式化程序尝试执行的操作
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(YEAR, 5, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(HOUR_OF_DAY, 2).appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.appendFraction(NANO_OF_SECOND, 0, 9, true)
.appendLiteral('Z')
.toFormatter();
Instant value = Instant.from(formatter.parse("48962-08-06T23:16:59.000Z"));
但是它失败了,
无法从TemporalAccessor获取即时信息:{},ISO解析为+48962-08-06T23:16:59,类型为java.time.format.Parsed
在我的机器上,以下代码解析您未来的年份:
public static void main(String[] args) {
String dateTime = "48962-08-06T23:16:59.000Z";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuu-MM-dd'T'HH:mm:ss.SSSz");
Instant instant = Instant.from(dtf.parse(dateTime));
System.out.println(instant);
}
和产出
+48962-08-06T23:16:59Z
我认为您的代码的问题在于其中一行(或两行)
.appendFraction(NANO_OF_SECOND, 0, 9, true)
.appendLiteral('Z')
因为字符串中Z
前面和点后面的三位数字可能不是纳秒,而是秒的分数。
另外一条可能也有问题,但我不能告诉你原因。我只知道当模式中的z
(小写)更改为z
(大写)时,我的答案会引发异常
您可以在DateTimeFormatter
中对其进行调整,然后再试一次,可能会奏效。我同意您的看法,最好的解决方案是使用生成器。下面一个用4位和5位数字分析年份:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 5, SignStyle.NOT_NEGATIVE)
.appendPattern("-MM-dd'T'")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffsetId()
.toFormatter();
String dateTime = "48962-08-06T23:16:59.000Z";
Instant i = formatter.parse(dateTime, Instant::from);
System.out.println(i);
代码段的输出为:
+48962-08-06T23:16:59Z
您的基本问题是字符串不符合ISO 8601,这是java.time类默认解析的标准,也就是说,没有任何显式格式化程序。ISO 8601中允许使用4位数以上的年份,但需要一个符号(如上面的输出所示)
你的代码出了什么问题?Joachim Sauer的评论是正确的:硬编码Z
作为文字是错误的。它与UTC的偏移量为0,需要将其解析为偏移量。由于格式化程序没有解析任何偏移量,因此无法根据解析的信息确定一个int时间点,即一个瞬间。这就是您的错误消息的含义:
无法从临时助理获取即时消息:{},ISO解析为+48962-08-06T23:16:59,类型为java.time.format.Parsed
这5位数字代表哪一年?是来自特定文化的日历,还是你真的想解析这么远的将来的一年?@Fildor Instant支持max to+100000000-12-31T23:59:59.9999999z
,那么我们如何解析它呢?@Fildor对我来说,这个问题似乎很明显,尽管他可能应该提到它。这就是“如何获得时间戳为48962-08-06T23:16:59.000Z的即时对象?”@deHaar只是我们需要的某个未来日期parse@IvoBeckersUpdateEdit肯定是Z
,这就是问题所在。OP解析基本上是LocalDateTime
:即没有时区信息的日期和时间。如果不知道应用哪个时区,就不能将其转换为即时的。因此,他们需要从外部提供时区(通过转换为LocalDateTime
,然后使用toInstant()
,提供时区),或者通过将.appendLiteral('Z')
替换为.appendZoneId()
来更改解析规则,将Z
解释为UTC指示符。