如何从模式创建 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:32:43  来源:igfitidea点击:

How to create Java time instant from pattern?

javajava-time

提问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?

如何Instantyyyy-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语义更丰富的类型,例如LocalDateTimeZonedDateTime就像使用 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.

在您的情况下,时间访问器可能包含它被解析的日期字段,但没有需要的“秒”字段InstantLocalDateTime在大多数情况下,最好使用语义更丰富的类型。

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直接使用,因为该类型是一种低级框架接口,不是大多数应用程序开发人员使用的。