如何从模式创建 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 Instant
from yyyy-MM-dd
pattern?
如何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.MAX
field 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 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
就像使用 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 Instant
needed. It is best to use the more semantically rich types like LocalDateTime
in 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:00
in 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.time
avoids defaulting these values)
字符串“9999-12-31”仅包含有关日期的信息。它不包含任何关于时间或偏移的信息。因此,没有足够的信息来创建Instant
. (其他日期和时间库更宽松,但java.time
避免默认这些值)
Your first choice is to use a LocalDate
instead 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 TemporalAccessor
directly, because that type is a low-level framework interface, not one for most application developers to use.
值得注意的是,这些可能性都没有TemporalAccessor
直接使用,因为该类型是一种低级框架接口,不是大多数应用程序开发人员使用的。