Pregunta

Al intentar utilizar el Calendario Gregoriano, me quedé atascado en una singularidad mientras calculaba el número de días transcurridos desde una fecha concreta.En el intérprete de Scala, ingresé:

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

No sé si importa el hecho de que 1976 sea un año bisiesto, pero los días 1 y 2 deberían haber estado separados por 1.Este es el único momento en la historia desde 1970 en el que ocurre esta singularidad.

Queriendo saber qué está pasando, calculo la diferencia entre las dos fechas mencionadas anteriormente, ¡y me da sólo exactamente 23 horas de diferencia!¿Qué pasó en esa fecha?Wikipedia aparentemente no dice nada al respecto.

Y aún más importante, ¿cómo calcular el número real de días transcurridos desde una fecha concreta?

¿Fue útil?

Solución

Si la opción de una división de flotación no está disponible, la mejor respuesta que puedo pensar es agregar una hora (1000 * 3600) mientras calcula una diferencia entre dos días:

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

Debería trabajar para cada fecha, ya que ya no sufre de las horas del salto.

Otros consejos

El problema

Los días de verano duran sólo 23 horas.

Y según este El 28 de marzo de 1976 era un día de verano al menos en París.La hora entre la 1 y las 2 de la madrugada de ese día simplemente no existía.

Aunque debe ser un problema de configuración regional ya que en mi computadora lo hago bien:

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

No estoy en París ni en ningún otro lugar que haya tenido un cambio de horario ese día;la hora cambió el 25 de abril de 1976 donde estoy.Entonces obtengo el comportamiento de "día omitido" en esa fecha:

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 señala en los comentarios que la razón probable por la que solo notas la diferencia de fecha incorrecta aquí es que todos los demás días de verano se compensan con los días de 25 horas que también ocurren en esos años, cuando se corrige el día de verano.

La solución

Utilice una biblioteca mejor para el procesamiento de fechas.El tiempo-joda La biblioteca lo hace correctamente (además de ser un mejor marco de fecha/hora en general):

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 señaló lo que creo: este día es un día de "tiempo de verano para el día". Como este día es de solo 23 h, la división euclidiana por un día es igual a 0.

De hecho, el uso de objetos Gregoriancalendar solo está utilizando una fecha como milisegundos, así que se divide por un día, ya que un entero solo trunca un resultado.

En lugar de una división de euclidia (entero), intente hacer una división de flotadores, luego redondear el resultado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top