Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Date 确定Java中时间范围表示的天数_Date_Time_Java 8 - Fatal编程技术网

Date 确定Java中时间范围表示的天数

Date 确定Java中时间范围表示的天数,date,time,java-8,Date,Time,Java 8,使用Java8时间,我只是想计算出一个时间范围内的天数。考虑以下事项: LocalDate start = LocalDate.of(2016, Month.MARCH, 28); LocalDate end = LocalDate.of(2016, Month.MARCH, 31); Period period = Period.between(start, end); 期间中的天数为3,表示两个日期之间的天数,包括开始和结束。我想要的是2个日期所代表的天数,实际上是4(3月28日、3月29

使用Java8时间,我只是想计算出一个时间范围内的天数。考虑以下事项:

LocalDate start = LocalDate.of(2016, Month.MARCH, 28);
LocalDate end = LocalDate.of(2016, Month.MARCH, 31);
Period period = Period.between(start, end);
期间中的天数为3,表示两个日期之间的天数,包括开始和结束。我想要的是2个日期所代表的天数,实际上是4(3月28日、3月29日、3月30日、3月31日)


我知道我可以把Period.between()返回的天数加上1,但我想我很惊讶,我找不到另一个调用来返回我想要的。我是否遗漏了什么,或者添加1是唯一的解决方案?

期间或
本地日期中似乎都没有包含结束日期的方法,因此似乎唯一要做的事情是:

Period.between(start, end.plusDays(1))


Period.between
只需调用
LocalDate.until

我相信您的天数计算与java的不同。根据文件规定的时间间隔: “包括开始日期,但不包括结束日期。”记住这一点-是的,添加1是唯一的解决方案。

tl;博士 始终通过半开放方法定义您的时间跨度,其中:

  • 开始是包容性的
  • 结尾是唯一的
如果您想要3月28日、3月29日、3月30日、3月31日这四天的时间,请将开始时间定为3月28日,结束时间定为4月1日。从第一天(3月28日)开始,一直到最后一天(4月1日),但不包括在内

2016-03-28/2016-04-01

半开 我错过什么了吗

您可能没有欣赏到半开放式方法在定义时间跨度方面的有用性

通常,定义时间跨度的最佳实践是半开放式方法。在半开放式中,开始是包含的,而结束是独占的

这种方法解决了处理分数秒的问题。直觉上,许多程序员会试图找到最后一个可能的时刻作为一段时间的结束。但最后一刻包含了无限可分的最后一秒。你可能会想,“好的,只需将小数点后三位改为毫秒,12:59.59.999表示中午午餐时间结束,因为这是我需要的所有解析,这就是遗留java.util.Date类的解析。”。但是,您将无法在数据库中找到匹配项,例如存储日期时间值的Postgres,其分辨率为微秒12:59:59.99999。所以你决定使用小数点后六位,x.999999。但是,在java.time类中,开始遇到与日期时间值不匹配的问题,并且您了解到提供九位小数秒的分辨率为纳秒,即x.99999999。你可以使用半开放式的方法,让这个令人沮丧的虫子旋转木马下船,在这种方法中,结局一直延续到下一整秒钟,但不包括下一整秒钟

我相信您会发现,在整个日期-时间处理代码(无论是否涉及小数秒)中,始终使用半开放方法将:

  • 使您的代码更易于阅读和理解
  • 减轻整体认知负荷。
    了解所有时间跨度都有相同的定义,消除了歧义
  • 减少bug
示例:

  • 中午午餐时间从时钟敲响中午(12:00:00)开始,一直到但不包括时钟敲响一点的时间。也就是说12点到13点
  • 一整天从一天的第一个时刻开始(,顺便说一下),一直持续到,但不包括,第二天的第一个时刻
  • 一周从星期一开始,一直持续到下一个星期一,但不包括下一个星期一。这意味着周一有七天
  • 一个月从月的第一个月开始,一直到下个月的第一个月,但不包括下个月的第一个月。所以三月是三月一号到四月一号

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
time类明智地使用了半开放方法。因此,正如问题中所指出的那样,该方法将结尾视为排他性的。我建议你顺其自然,而不是与之抗争。搜索Stack Overflow以了解更多有关此方法工作情况的示例

Period p = Period.between( start , stop );
p、 toString():P4D

ChronoUnit
如果需要总天数,例如一个半月45天,请使用enum,这是的一个实现。请参阅以进行讨论

同样,java.time类使用半开放方法。所以

long daysBetween = ChronoUnit.DAYS.between( start, stop );
四,

实时代码
请参见此示例。

方法的签名为

between(LocalDate startDateInclusive, LocalDate endDateExclusive) {

并且该方法没有重新加载,除了在给定结果中添加1之外,您别无选择…

期间。介于(开始、结束)之间。plusDays(1)
开始。直到(结束)。plusDays(1)
。我喜欢这个API,你可以用十几种不同的方法来做同样的事情……我有一个很大的问题:“三月是3月1日到4月1日。”如果我建议在我的工作中,那么他们可能会认为我疯了。四月一日是下个月!虽然我同意目前的日子计算的定义是好的(计数多少天添加到一个给定的开始),我仍然会考虑关闭日期间隔作为更好的选择,更接近大多数人认为日期间隔直观。但OP问题与时间间隔无关:日差和时间间隔是两个不同的问题/主题。对于时间间隔,半开是可以的。@MenoHochschild我听到了你的声音,还有你的位置
between(LocalDate startDateInclusive, LocalDate endDateExclusive) {