Tengo una pregunta complicada (al menos para mí) con las zonas horarias de Java. Comenzaré con un ejemplo que funciona como se esperaba:
TimeZone tz = TimeZone.getDefault(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(); simpleDateFormat.setTimeZone(tz); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(tz); calendar.set(Calendar.HOUR_OF_DAY, 0); System.out.println("0: " + simpleDateFormat.format(calendar.getTime())); calendar.set(Calendar.HOUR_OF_DAY, 1); System.out.println("1: " + simpleDateFormat.format(calendar.getTime())); calendar.set(Calendar.HOUR_OF_DAY, 2); System.out.println("2: " + simpleDateFormat.format(calendar.getTime()));producción:
0 4/28/17 12:27 AM 1: 4/28/17 1:27 AM 2: 4/28/17 2:27 AMY ahora un poco de magia:
TimeZone tz = TimeZone.getTimeZone("Africa/Cairo"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(); simpleDateFormat.setTimeZone(tz); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(tz); calendar.set(Calendar.HOUR_OF_DAY, 0); System.out.println("0: " + simpleDateFormat.format(calendar.getTime())); calendar.set(Calendar.HOUR_OF_DAY, 1); System.out.println("1: " + simpleDateFormat.format(calendar.getTime())); calendar.set(Calendar.HOUR_OF_DAY, 2); System.out.println("2: " + simpleDateFormat.format(calendar.getTime()));producción:
0: 4/28/17 1:31 AM 1: 4/28/17 1:31 AM 2: 4/28/17 2:31 AM¿Alguien podría explicarme por qué HOUR_OF_DAY para los valores 0 y 1 establecen la hora en el mismo valor para TimeZone específico?
Su máquina tiene una versión antigua de datos de zona horaria, en la que Egipto habría adelantado los relojes a la medianoche, hora local, a principios del 28 de abril de 2017. Por lo tanto, las 12:31 a. m. no habrían existido y Java se está adelantando una hora. en cambio 1 .
El 5 de julio de 2016, se publicaron los datos de la zona horaria 2016f de la IANA con el cambio a la zona horaria de África/Cairo para no observar el horario de verano a partir de ese momento. (Este fue un anuncio muy tardío, ya que el próximo cambio habría sido el 8 de julio de 2016).
Puede ver todas las transiciones para cada zona horaria de la IANA, en diferentes versiones de los datos de la IANA, en http://nodatime.github.io/tzvalidate/ . (Descargo de responsabilidad: construí esa página. Comencé el proyecto tzvalidate para validar que las diferentes bibliotecas de fecha/hora entiendan los datos de la zona horaria de la misma manera).
1 Yo diría que la API debería obligarlo a indicar lo que quiere que suceda en ese caso, pero no entraré en todo lo que está mal con java.util.Calendar aquí...
Hace algunos años, se planeó que esa zona horaria tuviera una transición de DST la noche del 28 de abril de 2017: a las 00:00 am, los relojes se habrían adelantado una hora. Por lo tanto, una hora entre la medianoche y la 1 a. m. no habría sido válida debido a la transición.
Sin embargo, esa transición no ocurrió en la práctica porque fue cancelada (Egipto parece haber cancelado y restablecido el horario de verano varias veces en los últimos años).
En conclusión, probablemente esté utilizando una versión anterior de Java que tiene una base de datos de zona horaria obsoleta.
Usted tenía razón. El problema fue con la transición de tiempo en el 28. Hoy todo funciona bien :)