简体   繁体   English

如何将 JSR-310 日期解析为 Instant?

[英]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_DAYCLOCK_HOUR_OF_DAYMINUTE_OF_DAYSECOND_OF_DAYMILLI_OF_DAYMICRO_OF_DAYNANO_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM