Problemas con zona horaria incorrecta en Android

Ahora la zona horaria correcta para Moscú es UTC +3 . Pero Android 4.4.4 sólo conoce UTC +4 para Moscú.

Y java.util.Date dar tiempo equivocado:

 Date now = new Date(); Sat Nov 21 00:37:24 GMT+04:00 2015 1448051844024 in (milliseconds) 

Uso de Joda org.joda.time

 DateTime nowWithCorrect = new DateTime() .withZone(DateTimeZone.forID("Europe/Moscow")); 2015-11-20T23:37:24.023+03:00 1448051844024 in (milliseconds) 

Pero el problema es que el usuario (en los dispositivos con zona horaria incorrecta) ha corregido manualmente el tiempo en el dispositivo. Y joda y java dan tiempo incorrecto en milisegundos.

Consigo del timestamp del servicio web y en el dispositivo calculo diferente con la hora local. Pero la hora local es incorrecta y da resultados incorrectos.

Quiero comprobar joda y java tiempo y manualmente para corregir timestamp.

Pregunta : ¿Puedo obtener diferentes entre la zona horaria y diferentes entre el tiempo en horas ( now y nowWithCorrect )? Por ejemplo: differentTimeZone = 1 , differentTimeHours = 1

Confundir los cambios de la zona horaria en Rusia

Rusia ha pasado por algunos confusos cambios de la zona horaria en los últimos años, con el desplazamiento de Moscú -desde-UTC cambiando de ida y vuelta entre +03:00 y +04:00 . Vea las páginas de Wikipedia sobre Tiempo en Rusia y Tiempo de Moscú .

Antes del otoño de 2011, Moscú tenía un tiempo estándar de +03:00 con un horario de verano (DST) de +04:00 .

A partir del otoño de 2011, Rusia tomó la decisión de permanecer permanentemente en DST, +04:00 , y suprimir el tiempo estándar de +03:00 . Vea este artículo de RT.com .

En julio de 2014, esa decisión se alteró drásticamente. Ahora Rusia está permanentemente en un tiempo estándar de +03:00 y ha abolido DST (no más +04:00 ).

Desactualizada tz base de datos

Asumo que sus problemas son debido a su base de datos de la zona horaria tz (antes conocida como la base de datos de Olson) que es anticuada. La verdadera plataforma Java tiene una base de datos tz, y su sistema operativo host probablemente tiene una base de datos tz. Joda-Time tiene su propia base de datos tz. Supongo que Android también, aunque no sé acerca de Android.

Obviamente mantener todas estas tz base de datos al día es una tarea real.

Para Joda-Time, simplemente reemplace su biblioteca Joda-Time por la última. Mientras que usted puede substituir apenas la base de datos del tz en Joda-Time, por lo que puedo recordar, virtualmente no hay problemas de compatibilidad con Joda-Time 2, así que no hay razón para no actualizar toda la biblioteca. Pero lea las notas de la versión para estar seguro. Si utiliza Joda-Time, este es el único requisito mínimo para la actualización; Yo recomendaría actualizar Android, Java, y el sistema operativo host, así, pero no es necesario.

Para la plataforma Java real, las versiones recientes facilitaban mucho la actualización de la base de datos tz. Las versiones anteriores requerían algo de hacking. Como alternativa, actualice al último Java 8 para obtener la última biblioteca.

Para su sistema operativo host, su sistema de actualización regular probablemente contiene actualizaciones tz. Sin embargo, algunas de esas actualizaciones pueden quedar rezagadas. Por lo tanto, es posible que deba realizar una actualización manual.

Trabajo en UTC

La mejor práctica para el trabajo de fecha y hora suele ser hacer todo el trabajo de back-end en UTC . La lógica de negocio, el almacenamiento de datos, la base de datos, el intercambio de datos, etc. deberían estar en UTC. Ajuste en una zona horaria como Europe/Moscow sólo cuando se espera / deseado por el usuario o el receptor de datos.

En Java 8 y posteriores, utilizaríamos el marco java.time integrado . Utilice Instant por un momento en UTC. Especifique un ZoneId para obtener ZonedDateTime cuando se ZonedDateTime una zona horaria. Pero la tecnología Java 8 aún no está disponible en Android. Creo que hay una biblioteca de back-port para java.time para Android, pero no sé los detalles.

Para Joda-Time , pregunte por el momento actual en UTC.

 DateTime nowUtc = DateTime.now( DateTimeZone.UTC ); 

Si no puede confiar en que el reloj local del dispositivo / equipo del usuario sea preciso y esté configurado correctamente, la hora de la fecha UTC será errónea . Nada puedes hacer sobre eso. En lugar confiar en una fuente externa, pero que asume una conexión de red.

Ajuste en el tiempo de Moscú según sea necesario.

 DateTime nowMoscow = nowUtc.withZone( DateTimeZone.forID( "Europe/Moscow" ) ); 

Si la base de datos tz del usuario para Joda-Time está obsoleta, esto devolverá un resultado incorrecto . No hay manera de evitar que como usted no puede predecir lo que las autoridades rusas harán al lado de sus reglas de mantenimiento del tiempo. La única solución es mantener tu aplicación actualizada con una biblioteca Joda-Time que tenga una base de datos tz actualizada. O, de nuevo, confíe en una fuente externa, como su servidor o algún otro servicio web, pero que supone una conexión de red.

Verifica la cuenta desde la época

Si te estás confundiendo y quieres verificar el valor verdadero de un objeto de fecha y hora, mira el recuento de la época .

Tanto Joda-Time como las clases java.util.Date/.Calendar anteriores cuentan milisegundos desde el primer momento de 1970 UTC. Estos valores se muestran en la Pregunta. Vea cómo ambos valores de milisegundos de la Cuestión son los mismos, por lo que el mismo momento en la línea de tiempo, pero un ajuste incorrecto en Moscú tiempo por la clase de Date de Android (casi seguramente debido a una base de datos tz obsoleta).

Tenga en cuenta que java.time utiliza un recuento diferente de la época, contando los nanosegundos de la misma época (1970 UTC). En Joda-Time, llame a getMillis para obtener el conteo de la época. En java.util.Date, llame a getTime .

  • ProGuard no compiló con Joda Time utilizado en Windows
  • Cómo obtener el formato de fecha de configuración regional en mes y día
  • Un ligero retraso al hacer clic en un botón
  • Convertir milisegundo a Joda Fecha Hora o para zona 0000
  • Android java.lang.NoClassDefFoundError utilizando las bibliotecas JODA
  • No se puede generar APK firmado con proguard habilitado cuando se usa Joda Time
  • Separar horas de minutos en un valor de tiempo dado
  • JodaTime no reconoce algunas zonas horarias de Android
  • Archivos duplicados copiados en APK al incluir Joda Time y bibliotecas de E / S comunes en el proyecto de Android
  • Recursos de la biblioteca con Robolectric 3 - JodaTime
  • Uso de la biblioteca Joda-Time para convertir la cadena al formato DateTime en Google Tasks API
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.