1976年3月28日到3月29日期间发生了什么与java.util.GregorianCalendar?

Mik*_*yer 20 java scala date gregorian-calendar long-integer

试图使用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
Run Code Online (Sandbox Code Playgroud)

我不知道1976年是闰年的事实是否重要,但是第1天和第2天本应该被分开1.这是自1970年以来唯一发生这种奇点的时刻.

想知道发生了什么,我计算了之前提到的两个日期之间的差异,它给我的时间差别只有23个小时!那天发生了什么?维基百科显然没有提及它.

更重要的是,如何计算自特定日期以来的实际天数?

dhg*_*dhg 46

问题

夏令时只有23个小时.

根据今年 3月28日的情况,1976年是至少巴黎的夏令时.那天凌晨1点到凌晨2点之间的时间根本不存在.

虽然它必须是一个Locale问题,因为在我的计算机上我做对了:

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
Run Code Online (Sandbox Code Playgroud)

那天我不在巴黎或其他任何有时间变化的地方; 时间在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
Run Code Online (Sandbox Code Playgroud)

Erwin在评论中指出,你唯一注意到这里不正确的日期差异的可能原因是所有其他夏令时日都被25小时的天数所抵消,这些天也发生在那些年,当夏令时被纠正时.

解决方案

使用更好的库进行日期处理.该乔达时间图书馆做它正确(以及作为一个更好的日期/时间框架总体):

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
Run Code Online (Sandbox Code Playgroud)

  • 也许其他1小时缺失或在所有其他日期添加的是偏移的(1 - 1 + 1 - 1 + 1 - 1 + 1 = 1) (5认同)

Arg*_*nir 4

如果浮点除法的选项不可用,我能想到的最佳答案是在计算两天之间的差异时添加一小时(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
Run Code Online (Sandbox Code Playgroud)

它应该适用于每个日期,因为您不再受到闰时的困扰。