简体   繁体   English

如何从模式创建Java时间瞬间?

[英]How to create Java time instant from pattern?

Consider a code: 考虑一下代码:

TemporalAccessor date = DateTimeFormatter.ofPattern("yyyy-MM-dd").parse("9999-12-31");
Instant.from(date);

The last line throws an exception: 最后一行抛出异常:

Unable to obtain Instant from TemporalAccessor: {},ISO resolved to 9999-12-31 of type java.time.format.Parsed

How to create Instant from yyyy-MM-dd pattern? 如何从yyyy-MM-dd模式创建Instant

The string "9999-12-31" only contains information about a date. 字符串“9999-12-31”仅包含有关日期的信息。 It does not contain any information about the time-of-day or offset. 它不包含有关时间或偏移的任何信息。 As such, there is insufficient information to create an Instant . 因此,没有足够的信息来创建Instant (Other date and time libraries are more lenient, but java.time avoids defaulting these values) (其他日期和时间库更宽松,但java.time避免默认这些值)

Your first choice is to use a LocalDate instead of an `Instant: 你的第一选择是使用LocalDate而不是`Instant:

LocalDate date = LocalDate.parse("9999-12-31");

Your second choice is to post process the date to convert it to an instant, which requires a time-zone, here chosen to be Paris: 你的第二个选择是发布处理日期以将其转换为瞬间,这需要一个时区,这里选择巴黎:

LocalDate date = LocalDate.parse("9999-12-31");
Instant instant = date.atStartOfDay(ZoneId.of("Europe/Paris")).toInstant();

Your third choice is to add the time-zone to the formatter, and default the time-of-day: 您的第三个选择是将时区添加到格式化程序,并默认为时间:

static final DateTimeFormatter FMT = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd")
    .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
    .toFormatter()
    .withZone(ZoneId.of("Europe/Paris"));
Instant instant = FMT.parse("9999-31-12", Instant::from);

(If this doesn't work, ensure you have the latest JDK 8 release as a bug was fixed in this area). (如果这不起作用,请确保您拥有最新的JDK 8版本,因为此区域中已修复了错误)。

It is worth noting that none of these possibilities use TemporalAccessor directly, because that type is a low-level framework interface, not one for most application developers to use. 值得注意的是,这些可能性都不直接使用TemporalAccessor ,因为该类型是低级框架接口,而不是大多数应用程序开发人员使用的接口。

The problem isn't the fact that you are using the year 9999. The Instant.MAX field evaluates to the timestamp 1000000000-12-31T23:59:59.999999999Z , so 9999 as a year is fine. 问题不在于您使用的是9999. Instant.MAX字段的计算结果为时间戳1000000000-12-31T23:59:59.999999999Z ,所以9999作为一年就可以了。

Dealing with TemporalAccessors instead of the more semantically rich types like LocalDateTime or ZonedDateTime is like using a Map to model an object and its properties instead of writing a class -- you have to assure that the value has the fields (like seconds, nanoseconds, etc) that are expected by something receiving it, rather than depending on formally declared operations in a higher level class to prevent dependencies from going unmet. 处理TemporalAccessors而不是像LocalDateTimeZonedDateTime这样的语义更丰富的类型就像使用Map来建模对象及其属性而不是编写class - 你必须确保该值具有字段(如秒,纳秒等) )接收它的东西所期望的,而不是依赖于更高级别类中的正式声明的操作来防止依赖性未被满足。

In your case it is likely that the temporal accessor contained the parsed date fields it was given, but didn't have a "seconds" field that the Instant needed. 在您的情况下,临时访问器可能包含它给出的已解析日期字段,但没有Instant所需的“秒”字段。 It is best to use the more semantically rich types like LocalDateTime in most instances. 在大多数情况下,最好使用更加语义丰富的类型,如LocalDateTime

Since you only have date fields, you should parse it as a date, then add the time fields before converting it to an Instant. 由于您只有日期字段,因此应将其解析为日期,然后在将其转换为Instant之前添加时间字段。 Here is one way, using LocalDate to parse the date: 这是一种方法,使用LocalDate来解析日期:

LocalDate localDate = LocalDate.parse("2016-04-17");
LocalDateTime localDateTime = localDate.atStartOfDay();
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
public static void main(String[] args) throws ParseException {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse("2016-12-31").toInstant());
}

the above code gives the following output: 上面的代码给出了以下输出:

2016-12-31T00:00:00Z 2016-12-31T00:00:00Z

i have answered this question using features('toInstant' method) of java 8. hope this answers your question... 我已经使用java 8的功能('toInstant'方法)回答了这个问题。希望这能回答你的问题......

Either you are only interested in the date itself (31st of December 9999), in which case the appropriate type would be a LocalDate : 要么您只对日期本身感兴趣(9999年12月31日),在这种情况下,相应的类型将是LocalDate

LocalDate date = LocalDate.parse("9999-12-31");

Or you do want an Instant , in which case you need to set a time and time zone, for example, 00:00 in Tokyo: 或者您确实想要一个Instant ,在这种情况下您需要设置时间和时区,例如东京的00:00

Instant instant = date.atStartOfDay(ZoneId.of("Asia/Tokyo")).toInstant();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从纪元微秒或纳秒创建Java Instant? - How do I create Java Instant from epoch microseconds or nanoseconds? 从java.time中的`ZonedDateTime`获取`Instant` - Get `Instant` from `ZonedDateTime` in java.time 从微秒创建Java DateTime Instant - Create Java DateTime Instant from microseconds java.time.Instant 是如何计算纳秒的? - How are nanoseconds calculated in java.time.Instant? 将Joda time Instant转换为Java time Instant - converting Joda time Instant to Java time Instant 如何从 Instant 和时间字符串构造 ZonedDateTime? - How to construct ZonedDateTime from an Instant and a time string? 如何从给定的 Instant 获取第二天结束的日期时间? (爪哇) - How to get next day end of day date time from given Instant ? (Java) 如何从MySQL DATETIME转换为java.time.Instant并在系统默认时区显示给用户? - How do I convert from MySQL DATETIME to java.time.Instant and display to user in system default timezone? 如何在 java.time.Instant 中获取和设置指定时间? - How to get and set specified time in java.time.Instant? 获取错误:日期中的from(java.time.Instant)无法应用于(org.threeten.bp.instant) - Getting error: from(java.time.Instant) in Date cannot be applied to (org.threeten.bp.instant)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM