使用Java 8时间我只是想弄清楚时间范围内代表的天数。请考虑以下事项:
LocalDate start = LocalDate.of(2016, Month.MARCH, 28);
LocalDate end = LocalDate.of(2016, Month.MARCH, 31);
Period period = Period.between(start, end);
期间的天数为3,表示两个日期之间的天数,包括开始日期和结束日期。我想要的是两个日期所代表的天数,实际上是4天(3月28日,3月29日,3月30日,3月31日)。
我知道我可以加上从Period.between()返回的天数加1,但我想我很惊讶我找不到另一个回复我想要的东西。我错过了什么或者只添加1个解决方案吗?
答案 0 :(得分:5)
始终通过 半开放 方法定义您的时间范围,其中:
当您想要March 28, March 29, March 30, March 31
的四天时,请从3月28日开始到4月1日结束。从第一个(3月28日)开始,一直运行这些日期,但不包括,最后一次(4月1日)。
2016年3月28日/ 2016年4月1日
我错过了什么
您可能会对半开放方法在定义时间跨度方面的实用性缺乏认识。
通常,定义时间跨度的最佳实践是半开放式方法。在半开放中,开头是包含,而结尾是独占。
这种方法解决了处理小数秒的问题。直观地说,许多程序员将试图找到最后一个可能的时刻作为一段时间的结束。但最后一刻涉及到无限可分的最后一秒。你可能会想,"嗯,只是在中午休息时间结束时前往小数点后三位,12:59.59.999,因为这是我将需要的所有分辨率,这就是遗留java.util.Date类。“但是你将无法在你的数据库中找到像Postgres那样的匹配项,它们以微秒12:59:59.999999的分辨率存储日期时间值。所以你决定使用小数的六位小数,x.999999。但是开始遇到与java.time类中的日期时间值不匹配的情况,并且您学习了提供分数秒的九位数x.999999999的纳秒分辨率。你可以通过使用半开放式方法来解决这个令人沮丧的错误轮播,其结尾可以达到但不包括下一整秒。
我相信您会发现在整个日期时间处理代码中一致使用半开放式方法(无论是否涉及小数秒):
示例:
LocalDate
而不是添加1
以获得总天数,而是将您的时间跨度定义为半开放:开头是包含,结尾是独占。如果您试图代表3月28日,29日,30日和31日的四个日期,那么我建议您定义3月28日到4月1日的时间段。
LocalDate start = LocalDate.of( 2016, Month.MARCH, 28 ) ; // inclusive
LocalDate stop = LocalDate.of( 2016, Month.APRIL, 1 ) ; // exclusive
Period
java.time类明智地使用半开放方法。因此,Period.between
方法将结尾视为独占,如问题中所述。我建议你在这里顺其自然,而不是去战斗。搜索Stack Overflow以获取有关此方法运作情况的更多示例。
Period p = Period.between( start , stop );
p.toString():P4D
ChronoUnit
如果您想要总天数,例如一个半月的45天,请使用ChronoUnit
枚举,TemporalUnit
的实现。请参阅this Question进行讨论。
同样,java.time类使用半开放方法。所以
long daysBetween = ChronoUnit.DAYS.between( start, stop );
4
请参阅此示例code run live at IdeOne.com。
答案 1 :(得分:2)
在Period
或LocalDate
中,似乎并不是一个包容性的结束日期方法,因此似乎唯一要做的事情就是:
Period.between(start, end.plusDays(1))
或
start.until(end.plusDays(1))
(Period.between
只调用LocalDate.until
)
答案 2 :(得分:1)
我相信你的日常计数与java不同。 Period.between根据文档:http://docs.oracle.com/javase/8/docs/api/java/time/Period.html#between-java.time.LocalDate-java.time.LocalDate- “包括开始日期,但结束日期不包括在内。”考虑到这一点 - 是的,添加1是唯一的解决方案。
答案 3 :(得分:0)
方法的签名是
between(LocalDate startDateInclusive, LocalDate endDateExclusive) {
并且该方法没有被加载,除了在给定结果中添加1之外别无选择......