Java.time.Period转换为秒数。

4
如何将java.time.Period转换为秒?
下面的代码产生了意想不到的结果。
java.time.Period period = java.time.Period.parse( "P1M" );
final long days = period.get( ChronoUnit.DAYS ); // produces 0
final long seconds = period.get( ChronoUnit.SECONDS ); // throws exception

我在寻找Java 8的等价物,与以下内容相同:

// import javax.xml.datatype.DatatypeFactory;
// import javax.xml.datatype.Duration;

DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
Duration d1 = datatypeFactory.newDuration( "P1M" ); 
final long sec = d1.getTimeInMillis( new Date() ) / 1000;

Period 被描述为“基于日期的时间量”。它不支持比天更精细的字段。无论如何,“一个月中的秒数”可能有什么正确答案呢? - khelwood
1
所以我没有理解重点。旧的类javax.xml.datatype.Duration比新的java.time.Period和Duration组合更好吗?我以为迁移到Java 8会给我带来好处,但是我发现最好还是保持旧代码,不要触碰Java 8中的Period和Duration类。 - Seweryn Habdank-Wojewódzki
2个回答

12

正如在文档中所述,Period是以天、月和年为单位表示的一段时间;您的示例是“一个月”。

一个月的秒数不是固定值。二月份有28或29天,而十二月份有31天,因此从(例如)2月12日开始算的“一个月”比从12月12日开始算的“一个月”少一些秒。偶尔(比如去年),12月份会出现闰秒。根据时区和月份,它可能会多出30分钟、1小时或1小时半;或者因为进入或退出夏令时而少那么多时间。

你只能问:“从这个日期这个时区开始,下一个[时间段]有多少秒?”(或者,“在[带有时区的日期]之前的最后[时间段]有多少秒?”)没有参考点,这样问就没有意义。 (您现在已更新问题并添加了一个参考点:“现在”。)

如果我们引入一个参考点,那么您可以使用Temporal(例如LocalDateTimeZonedDateTime)作为参考点,并使用它的until方法与ChronoUnit.MILLIS。例如,在本地时间从“现在”开始:

LocalDateTime start = LocalDateTime.now();
Period period = Period.parse("P1M");
LocalDateTime end = start.plus(period);
long milliseconds = start.until(end, ChronoUnit.MILLIS);
System.out.println(milliseconds);

实时复制

当然,可以更加简洁,我想展示每一步。更简洁:

LocalDateTime start = LocalDateTime.now();
System.out.println(start.until(start.plus(Period.parse("P1M")), ChronoUnit.MILLIS));

说实话,我不同意所有这些降级和最后的陈述,如果我们认为javax.xml.datatype.Duration类是正确的。例如,代码运行良好: DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); Duration d1 = datatypeFactory.newDuration( "P1M" ); final long sec = d1.getTimeInMillis( new Date() ); - Seweryn Habdank-Wojewódzki
@SewerynHabdank-Wojewódzki:java.xml.datatype.DurationgetTimeInMillis 支持 我最后的陈述:注意它接受一个时间参考点作为参数。你的代码告诉你从"现在"开始的一个月有多少毫秒。要做到相同的效果,使用ZonedDateTimeplus方法,并传入你的Period,然后确定两个时间点之间的毫秒数。 - T.J. Crowder
如果我期望P1M中的秒数是固定值,我会在应用程序中定义一个“常量”值,并且不使用Period类。 - Seweryn Habdank-Wojewódzki
1
这是我问题的核心。获取秒数的最佳方式是什么?我知道评论者们认为我很笨。但对我来说,如何使用Java 8的精神进行这样的计算还不清楚。 特别是ava.xml.datatype.Duration可以同时保存基于日期的Period/Duriation和基于时间的Period/Duriation。Java 8将责任分割开来,在字符串可能是时间或日期的情况下会出现问题。所以我的目标不是获得固定的值,而是希望能够正确地使用Java 8 API进行这个计算。 - Seweryn Habdank-Wojewódzki
@SewerynHabdank-Wojewódzki:我已经更新了答案,展示了使用Java 8 API获取一个月后的方法("from now"是你问题中缺失的部分)。 - T.J. Crowder

-2

“get”方法只接受ChronoUnit.YEARS、ChronoUnit.MONTHS和ChronoUnit.DAYS。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接