如何从模式创建 Java 时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37672012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create Java time instant from pattern?
提问by Cherry
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 Instantfrom yyyy-MM-ddpattern?
如何Instant从yyyy-MM-dd模式创建?
回答by Abhishek
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 的 features('toInstant' method) 回答了这个问题。希望这能回答你的问题......
回答by Hank D
The problem isn't the fact that you are using the year 9999. The Instant.MAXfield evaluates to the timestamp 1000000000-12-31T23:59:59.999999999Z, so 9999 as a year is fine.
问题不在于您使用的是 9999 年。该Instant.MAX字段的计算结果为 timestamp 1000000000-12-31T23:59:59.999999999Z,因此将 9999 作为一年就可以了。
Dealing with TemporalAccessorsinstead of the more semantically rich types like LocalDateTimeor ZonedDateTimeis like using a Mapto 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就像使用 aMap对对象及其属性进行建模而不是编写 a 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 Instantneeded. It is best to use the more semantically rich types like LocalDateTimein most instances.
在您的情况下,时间访问器可能包含它被解析的日期字段,但没有需要的“秒”字段Instant。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. Here is one way, using LocalDate to parse the date:
由于您只有日期字段,您应该将其解析为日期,然后在将其转换为 Instant 之前添加时间字段。这是一种方法,使用 LocalDate 来解析日期:
LocalDate localDate = LocalDate.parse("2016-04-17");
LocalDateTime localDateTime = localDate.atStartOfDay();
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
回答by assylias
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:00in Tokyo:
或者你确实想要一个Instant,在这种情况下你需要设置一个时间和时区,例如,00:00在东京:
Instant instant = date.atStartOfDay(ZoneId.of("Asia/Tokyo")).toInstant();
回答by JodaStephen
The string "9999-12-31" only contains information about a date. It does not contain any information about the time-of-day or offset. As such, there is insufficient information to create an Instant. (Other date and time libraries are more lenient, but java.timeavoids defaulting these values)
字符串“9999-12-31”仅包含有关日期的信息。它不包含任何关于时间或偏移的信息。因此,没有足够的信息来创建Instant. (其他日期和时间库更宽松,但java.time避免默认这些值)
Your first choice is to use a LocalDateinstead of an `Instant:
您的第一个选择是使用 aLocalDate而不是 `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 TemporalAccessordirectly, because that type is a low-level framework interface, not one for most application developers to use.
值得注意的是,这些可能性都没有TemporalAccessor直接使用,因为该类型是一种低级框架接口,不是大多数应用程序开发人员使用的。

