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(如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);

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 支持 我的最后陈述:注意它是如何接受一个时间点作为参数的。您的代码告诉您从“现在”开始的月份有多少毫秒。为此,请使用ZonedDateTimeplus 并传入您的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 到秒的主要内容,如果未能解决你的问题,请参考以下文章

Win10时钟精确到秒

苹果手机如何让状态列时间精确到秒,求高人

mysql 5.6 datetime 保存精确到秒

mybatis 插入日期类型精确到秒的有关问题

毫秒到秒 JS 二分查找

log15 库将纪元时间从纳秒到秒进行记录