zonas zona tiempo significa que paises obtener mundo husos horas horarios horario horarias horaria entre diferencia coordinado conversor javascript java date calendar timezone

javascript - tiempo - La zona horaria de Java Date imprime diferentes zonas horarias para diferentes años, se necesita una solución alternativa



utc horario (4)

Al probar mi aplicación tengo un problema extraño. Cuando coloco una fecha el año anterior a 1945, cambia la zona horaria.

Tengo este programa simple para mostrar el problema.

public static void main(String[] args) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); Calendar calendar = Calendar.getInstance(); System.out.println("**********Before 1945"); calendar.set(1943, Calendar.APRIL, 12, 5, 34, 12); System.out.println(format.format(calendar.getTime())); System.out.println(calendar.getTime()); System.out.println("**********After 1945"); calendar.set(1946, Calendar.APRIL, 12, 5, 34, 12); System.out.println(format.format(calendar.getTime())); System.out.println(calendar.getTime()); }

La salida que estoy recibiendo es a continuación:

**********Before 1945 1943-04-12 05:34:12+0630 Mon Apr 12 05:34:12 IDT 1943 **********After 1945 1946-04-12 05:34:12+0530 Fri Apr 12 05:34:12 IST 1946

Para el primero, lo +0630 como +0630 e IDT , mientras que para el segundo, +0530 e IST que se espera.

Editar:-

Después de ver la respuesta de @Elliott Frisch, intenté una cita antes de 1942:

calendar.set(1915, Calendar.APRIL, 12, 5, 34, 12); System.out.println(format.format(calendar.getTime())); System.out.println(calendar.getTime());

salida:-

1915-04-12 05:34:12+0553 Mon Apr 12 05:34:12 IST 1915

Aquí otra vez, dice IST pero muestra +0553 . ¿No debería ser +0530 .

Solo para una comparación, intenté lo mismo en javascript: -

new Date("1946-04-12 05:34:12") //prints Fri Apr 12 1946 05:34:12 GMT+0530 (IST) new Date("1943-04-12 05:34:12") //prints Fri Apr 12 1943 05:34:12 GMT+0530 (IST) new Date("1915-04-12 05:34:12") //prints Mon Apr 12 1915 05:34:12 GMT+0530 (IST)

Que funciona bien. Quiero saber por qué Java se ve afectado por él y, si se trata de un problema conocido, cuál es la posible solución para ello .

Gracias por adelantado.


java.time

Evite el uso de las antiguas y problemáticas clases de fecha y hora incluidas con las primeras versiones de Java. Ahora legado, suplantado por las clases java.time .

ZoneId z = ZoneId.of( "Asia/Kolkata" ); // "Asia/Calcutta" LocalTime lt = LocalTime.of( 5 , 34 , 12 ); ZonedDateTime zdt1943 = ZonedDateTime.of( LocalDate.of( 1943 , Month.APRIL , 12 ) , lt , z ); ZonedDateTime zdt1945 = ZonedDateTime.of( LocalDate.of( 1945 , Month.APRIL , 12 ) , lt , z ); ZonedDateTime zdt1946 = ZonedDateTime.of( LocalDate.of( 1946 , Month.APRIL , 12 ) , lt , z ); ZonedDateTime zdt2016 = ZonedDateTime.of( LocalDate.of( 2016 , Month.APRIL , 12 ) , lt , z );

Volcar a la consola.

System.out.println( "zdt1943: " + zdt1943 ); System.out.println( "zdt1945: " + zdt1945 ); System.out.println( "zdt1946: " + zdt1946 ); System.out.println( "zdt2016: " + zdt2016 );

Ver código en vivo en IdeOne.com .

Cuando se ejecuta Vemos el mismo comportamiento que se describe en su pregunta, con un offset-from-UTC de seis horas y media durante la guerra y cinco y media después. Obtenemos el mismo comportamiento si usamos Asia/Kolkata o Asia/Calcutta . Las clases java.time usan tzdata , anteriormente conocido como Olson Database .

zdt1943: 1943-04-12T05: 34: 12 + 06: 30 [Asia / Calcuta]

zdt1945: 1945-04-12T05: 34: 12 + 06: 30 [Asia / Calcuta]

zdt1946: 1946-04-12T05: 34: 12 + 05: 30 [Asia / Calcuta]

zdt2016: 2016-04-12T05: 34: 12 + 05: 30 [Asia / Calcuta]

En la pregunta ...

Cuando coloco una fecha el año anterior a 1945, cambia la zona horaria.

No, no cambia la zona horaria. Los resultados dicen que en los años anteriores "5:34" se definió como seis horas y media por delante de UTC mientras que en los años posteriores la definición se convirtió en cinco horas y media por delante de UTC. Así como "5:34" significa ocho horas detrás de UTC en Seattle en el verano, pero siete horas en el invierno, debido a la tontería del horario de verano (DST) .

Pero sospecho que estos valores pueden ser erróneos; sigue leyendo

Tiempo en Calcuta

El comportamiento que estamos viendo no parece coincidir con mi lectura de esta página de Wikipedia, Time in Calcutta . Esa página describe compensaciones impares distintas a la hora o la media hora, como UTC+05:54 , que no estamos viendo en ninguno de nuestros ejemplos de código respectivos.

Entonces sospecho que tzdata no contiene estos datos históricos para India. Pero solo la conjetura de este laico; No soy un historiador.

No use tipos de fecha y hora para valores históricos

Si bien no conozco los detalles del tiempo en este período histórico de la India y su manejo en tzdata, parece que ninguna de nuestras bibliotecas de fecha y hora están manejando estos matices históricos.

¡Pero no debemos esperar tal manejo! Sepa que tzdata no promete una cobertura completa de las zonas horarias antes de 1970 .

Cuando se hace referencia a valores históricos de fecha y hora, le sugiero que utilice simplemente texto en lugar de cualquiera de los tipos de datos de fecha y hora. El propósito de los tipos de datos es para la validación y el cálculo. Probablemente no estés haciendo ni por valores históricos. No puedo imaginar que esté determinando el número de días que una factura está vencida desde 1943.

Tal vez debería editar su pregunta para describir por qué almacena estos valores históricos de fecha y hora en una base de datos con tanta precisión. Si solo estaba experimentando y notó estos problemas, tenga en cuenta que no debe esperar un manejo preciso de la fecha y la hora en el pasado (antes de 1970) ni en el futuro (en el transcurso de las pocas semanas en que los políticos a veces dan información sobre cambios repentinos en la definición de la zona horaria) .

Resultado: el intento de manejar con precisión los valores históricos de fecha y hora está cargado de varios problemas y me parece inútil.

¿Cuál es la posible solución para ello?

Sugiero utilizar valores de fecha y hora "locales" como texto en formato ISO 8601 sin ninguna zona horaria.


Este es probablemente el comportamiento esperado de Java (y no de JavaScript).

Como lo indica el comentario de RobG anterior, los lenguajes de programación pueden o no admitir las reglas de tiempo históricas (como DST y compensaciones de zona horaria). En su caso, parece que su tiempo de ejecución de Java lo admite, mientras que su tiempo de ejecución de JavaScript no lo admite.

Puede encontrar una lista de zonas horarias históricas y reglas de horario de verano para India en timeanddate.com . La lista confirma las compensaciones de la zona horaria de sus fechas de Java:

  • Hasta 1941: UTC + 5: 53: 20
  • 1941: UTC + 6: 30
  • 1942: UTC + 5: 30
  • 1943-44: UTC + 6: 30
  • Desde 1945: UTC + 5: 30.

La comparación de sus fechas con Wolfram | Alpha confirma aún más sus compensaciones UTC de Java date: 1915 , 1943 , 1946

Wikipedia proporciona más información sobre el tiempo en la India :

El tiempo de Calcuta se mantuvo oficialmente como una zona horaria separada hasta 1948

El tiempo de Calcuta se puede especificar como UTC + 5: 54 o UTC + 5: 53: 20. Este último es consistente con su ejemplo de código.

La entrada de Wikipedia informa además que la zona horaria actual IST con un desplazamiento de UTC + 5: 30 no estuvo en plena vigencia en toda la India hasta 1955.

Como lo señaló Elliott Frisch y lo confirmó el enlace a timeanddate.com anterior, DST estuvo vigente durante la Segunda Guerra Mundial. En su comentario a su respuesta, usted declara:

Es esta la forma en que se supone que debemos guardar en la base de datos y usarla en las aplicaciones, o utilizamos alguna solución alternativa para ella.

Supongo que depende. Si realmente necesita distinguir fechas como puntos en el tiempo con precisión, necesitaría una representación independiente de la zona horaria, como el tiempo UTC o Unix (o milisegundos desde la época de Unix). Si solo trabaja con fechas locales de la misma zona horaria, una simple representación de cadena (por ejemplo, YYYY-MM-DD hh: mm: ss) podría ser suficiente.


Hubo una war . Desde el enlace de wikipedia, India observó horario de verano durante la Segunda Guerra Mundial, desde 1942-1945.


Recomendaría mantener el equivalente de la época de las fechas en la base de datos. Creo que, independientemente de los ahorros de luz diurnos, la hora y la fecha de un período representan el real, ya sea IDT o IST. Yo usaría el ejemplo https://.com/a/6687502 y convertiría todas las fechas a la época y las almacenaría en DB. Invertiré la lógica para mostrar la fecha y la hora desde la base de datos junto con el indicador IDT / IST para evitar la confusión para el usuario.