java.time.Period 到秒
Posted
技术标签:
【中文标题】java.time.Period 到秒【英文标题】:java.time.Period to seconds 【发布时间】:2017-01-27 12:21:26 【问题描述】:如何将 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
被描述为“基于日期的时间量”。它不支持比天更精细的字段。无论如何,“一个月的秒数”的正确答案可能是什么?
所以我没有明白这一点。较旧的类 javax.xml.datatype.Duration 与较新的 java.time.Period 和 Duration 组合要好得多?我认为迁移到 Java 8 会给我带来好处,但我认为最好还是保留旧代码,不要接触 Java 8 中的 Period 和 Duriation 类。
【参考方案1】:
正如the documentation 中所说,Period
是以天、月和年表示的时间段;你的例子是“一个月”。
一个月的秒数不是固定值。 2 月有 28 或 29 天,而 12 月有 31 天,因此(比如说)2 月 12 日的“一个月”比 12 月 12 日的“一个月”的秒数少。有时(例如去年),12 月会有闰秒。根据时区和月份,它可能会多出 30 分钟、一个小时或一个半小时;或比平时少得多,这要归功于进入或退出夏令时。
你只能问“从这个时区的这个日期开始,接下来的[时间段]还有多少秒?” (或者,“[date-with-timezone] 之前的最后 [period] 有多少秒?”)如果没有参考点,你不能问它,这没有意义。 (您现在已更新问题以添加参考点:“现在”。)
如果我们引入一个参考点,那么您可以使用Temporal
(如LocalDateTime
或ZonedDateTime
)作为参考点,并将其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);
Live Copy
当然,这可以更简洁,我想展示每个步骤。更简洁:
LocalDateTime start = LocalDateTime.now();
System.out.println(start.until(start.plus(Period.parse("P1M")), ChronoUnit.MILLIS));
【讨论】:
老实说,如果我们认为 javax.xml.datatype.Duration 类是正确的,我不同意所有这些降级和最后一条语句。例如代码运行良好: DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();持续时间 d1 = datatypeFactory.newDuration("P1M");最终长秒 = d1.getTimeInMillis(new Date()); @SewerynHabdank-Wojewódzki:java.xml.datatype.Duration
's getTimeInMillis
支持 我的最后陈述:注意它是如何接受一个时间点作为参数的。您的代码告诉您从“现在”开始的月份有多少毫秒。为此,请使用ZonedDateTime
的plus
并传入您的Period
,然后确定两个时间点之间的毫秒数。
如果我希望 P1M 中的秒数是固定值,我会在应用程序中定义“常量”值并且不使用 Period 类。
这是我问题的核心。获得秒数的最佳方法是什么。我知道审稿人认为我是白痴。但对我来说,现在还不清楚用 Java 8 精神进行这样的计算。特别是 ava.xml.datatype.Duration 可能同时包含基于日期的 Period/Duration 和基于时间的 Period/Duration。 Java 8 责任分离,当字符串可能是时间或日期时,是什么在使用中出现问题。因此,我的重点不是固定任何值,但我希望在 Java 8 API 方面能够很好地完成这个计算。
@SewerynHabdank-Wojewódzki:我已经更新了答案,以显示一种获得一个月从现在开始的方法(“从现在开始”是您问题中缺少的部分)使用 Java 8 API。【参考方案2】:
“get”方法只接受 ChronoUnit.YEARS、ChronoUnit.MONTHS 和 ChronoUnit.DAYS。
【讨论】:
以上是关于java.time.Period 到秒的主要内容,如果未能解决你的问题,请参考以下文章