1976年3月28日和3月29日之间发生了什么与java.util.gregoriancalendar?
-
12-12-2019 - |
题
试图使用gregoriancalendar,我在计算自特定日期以来的天数时陷入奇点。 在Scala解释器中,我输入了:
scala>import java.util.GregorianCalendar
scala>import java.util.Calendar
scala>val dateToday = new GregorianCalendar(2012,Calendar.MAY,22).getTimeInMillis()
dateToday: Long = 1337637600000
scala>val days1 = (dateToday - (new GregorianCalendar(1976,Calendar.MARCH,28).getTimeInMillis())) / (1000*3600*24)
days1: Long = 13203
scala>val days2 = (dateToday - (new GregorianCalendar(1976,Calendar.MARCH,29).getTimeInMillis())) / (1000*3600*24)
days2: Long = 13203
.
我不知道1976年是闰年的事实,但是第1天和第2天应该分开了1.这是自1970年以来历史上唯一的时刻,这种奇点发生了。
想要知道发生了什么,我计算先前提到的两个日期之间的差异,它给我只有23个小时的区别!那个日期发生了什么?维基百科显然对此没有说。
甚至更重要,如何计算自特定日期以来的真实天数?
解决方案
如果浮动划分的选项不可用,我可以想到的最佳答案是添加一小时(1000 * 3600),同时计算两天之间的差异:
scala> (dateToday - (new GregorianCalendar(1976, Calendar.MARCH, 28).getTimeInMillis()) + 1000*3600) / (1000 * 3600 * 24)
days1: Long = 13204
scala> (dateToday - (new GregorianCalendar(1976, Calendar.MARCH, 29).getTimeInMillis()) + 1000*3600) / (1000 * 3600 * 24)
days1: Long = 13203
.
它应该为每一日期工作,因为您不再遭受闰时。
其他提示
问题
日光储蓄天只有23小时。
并根据这个 3月28日,1976年3月28日是夏令时的日子至少巴黎。那天上午1点到凌晨2点之间的时间根本不存在。
虽然它必须是自我的电脑以来的语言环境问题,但我得到它正确:
scala> val days1 = (dateToday - (new GregorianCalendar(1976, Calendar.MARCH, 28).getTimeInMillis())) / (1000 * 3600 * 24)
days1: Long = 13203
scala> val days2 = (dateToday - (new GregorianCalendar(1976, Calendar.MARCH, 29).getTimeInMillis())) / (1000 * 3600 * 24)
days2: Long = 13202
.
我不在巴黎或其他任何地方在那天有时间变化;时间发生在1976年4月25日。所以我在该日期获得“跳过的日”行为:
scala> val days3 = (dateToday - (new GregorianCalendar(1976, Calendar.APRIL, 25).getTimeInMillis())) / (1000 * 3600 * 24)
days3: Long = 13175
scala> val days4 = (dateToday - (new GregorianCalendar(1976, Calendar.APRIL, 26).getTimeInMillis())) / (1000 * 3600 * 24)
days4: Long = 13175
.
Erwin在评论中,可能的原因是您唯一注意到的,这在此处的错误日期差异是所有其他日光储蓄日抵消了在那些年份也发生的25小时内,当时夏令时纠正。
解决方案
使用更好的库进行日期处理。 joda-time 图书馆是正确的(以及总体上的更好的日期/时间框架):
import org.joda.time.Days
import org.joda.time.DateTimeConstants
import org.joda.time.DateMidnight
val d1 = new DateMidnight(1976, DateTimeConstants.APRIL, 25)
val d2 = new DateMidnight(1976, DateTimeConstants.APRIL, 26)
val x = Days.daysBetween(d1, d2).getDays()
println(x) // 1
. DHG指出了我的想法:这一天是一个“夏令时”一天。 因为这一天只有23小时,欧几里德师一天等于0。
实际上,使用gregoriancalendar对象仅使用日期为毫秒,因此将一天除以整数只截断结果。
而不是欧几里德(整数)划分,尝试做一个浮子划分,然后绕过结果。
不隶属于 StackOverflow