То, что произошло в период с 29 марта и 29 марта 1976 года с Java.util.gregoriancalendar?
-
12-12-2019 - |
Вопрос
Попытка использовать григорианкалендар, я застрял на особенности во время вычисления количества дней с определенной даты. В переводчике 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 часов.
и в соответствии с Это 28 марта 1976 года была день летнего года в Наименее Париж. Час от 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
.
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
.
решение
Используйте лучшую библиотеку для обработки даты. 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 использует только дату в качестве миллисекунды, поэтому разделяют на один день в качестве целого числа, только укореняется.
вместо евклидианского (целочисленного) дивизии, попытайтесь сделать поплавок, затем вокруг результата.