[英]How to parse JSR-310 date to Instant?
I'm trying to parse lets say "2020-01-12+01:00"
with JSR-310 time.我正在尝试用 JSR-310 时间解析"2020-01-12+01:00"
。
I read it via DateTimeFormatter.ofPattern("yyyy-MM-ddVV")
, however now if I want to transform that into a Instant via Instant.from(DateTimeFormatter.ofPattern("yyyy-MM-ddVV").parse("...")
, it throws where it complains that time
is null.我通过DateTimeFormatter.ofPattern("yyyy-MM-ddVV")
读取它,但是现在如果我想通过Instant.from(DateTimeFormatter.ofPattern("yyyy-MM-ddVV").parse("...")
,它抛出它抱怨time
为空的地方。
Which granted it is, but, I'd like to get Instant from that, ie epochMillis, so I can serialize the long
into a database.这是当然的,但是,我想从中获取 Instant,即 epochMillis,这样我就可以将long
序列化到数据库中。
Is there a way around it?有办法解决吗? Basically I'd like to extend the "2020-01-12+01:00"
to "2020-01-12T00:00.000+01:00"
and parse that to Instant as usual基本上我想将"2020-01-12+01:00"
扩展到"2020-01-12T00:00.000+01:00"
并像往常一样将其解析为 Instant
You need to use DateTimeFormatterBuilder
, specifying ISO_DATE
format and a default time-of-day (midnight 1 ):您需要使用DateTimeFormatterBuilder
,指定ISO_DATE
格式和默认时间(午夜1 ):
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_DATE)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter();
Instant instant = Instant.from(formatter.parse("2020-01-12+01:00"));
System.out.println(instant);
1) The ChronoField
can be any time- of-day field, ie HOUR_OF_DAY
, CLOCK_HOUR_OF_DAY
, MINUTE_OF_DAY
, SECOND_OF_DAY
, MILLI_OF_DAY
, MICRO_OF_DAY
, or NANO_OF_DAY
. 1) ChronoField
可以是一天中的任何时间字段,即HOUR_OF_DAY
、 CLOCK_HOUR_OF_DAY
、 MINUTE_OF_DAY
、 SECOND_OF_DAY
、 MILLI_OF_DAY
、 MICRO_OF_DAY
或NANO_OF_DAY
。
Output输出
2020-01-11T23:00:00Z
If you want to retain the time zone offset, you need to use OffsetDateTime
(or ZonedDateTime
) instead of Instant
:如果要保留时区偏移量,则需要使用OffsetDateTime
(或ZonedDateTime
)而不是Instant
:
OffsetDateTime dateTime = OffsetDateTime.parse("2020-01-12+01:00", formatter);
System.out.println(dateTime);
System.out.println(dateTime.format(DateTimeFormatter.ISO_DATE));
Output (from both OffsetDateTime and ZonedDateTime)输出(来自 OffsetDateTime 和 ZonedDateTime)
2020-01-12T00:00+01:00
2020-01-12+01:00
You can use LocalDate.parse(dateString, formatter)
using the Formatter
you've made above to give you a LocalDate
instance.您可以使用上面创建的Formatter
使用LocalDate.parse(dateString, formatter)
为您提供LocalDate
实例。
LocalDate
can then give you a LocalDateTime
at any time in that day, but (for example) you can get the start of day from it. LocalDate
然后可以在当天的任何时间为您提供LocalDateTime
,但是(例如)您可以从中获取一天的开始。
LocalDateTime
has a toInstant
method to give you an Instant
. LocalDateTime
有一个toInstant
方法可以给你一个Instant
。
Instant
has a toEpochMilli
method to get your long
. Instant
有一个toEpochMilli
方法来获取你的long
。
It's easy enough when you know how.当您知道如何操作时,这很容易。 The formatter we need is built in. There's a complication in the fact that there isn't a type to parse the string into, no OffsetDate
.我们需要的格式化程序是内置的。有一个复杂的事实是没有将字符串解析为的类型,没有OffsetDate
。 I present two options for tackling this.我提出了解决这个问题的两种选择。
String s = "2020-01-12+01:00";
TemporalAccessor parsed = DateTimeFormatter.ISO_OFFSET_DATE.parse(s);
LocalDate date = LocalDate.from(parsed);
ZoneOffset offset = ZoneOffset.from(parsed);
Instant result = date.atStartOfDay(offset).toInstant();
System.out.println(result);
Output from this snippet is:这个片段的输出是:
2020-01-11T23:00:00Z 2020-01-11T23:00:00Z
We seldom need to use the TemporalAccessor
interface directly, and it's considered low-level.我们很少需要直接使用TemporalAccessor
接口,它被认为是低级的。 It also isn't the only way to go here.这也不是去这里的唯一途径。 The other good option is to define a default time of day so we can parse directly into an Instant
:另一个不错的选择是定义一天中的默认时间,以便我们可以直接解析为Instant
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_OFFSET_DATE)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.toFormatter();
Instant result = formatter.parse(s, Instant::from);
The result is the same as before.结果和之前一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.