[英]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
而不是像LocalDateTime
或ZonedDateTime
这样的语义更丰富的类型就像使用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.