Cómo hacer frente a los ahorros de luz diurna con TimeZone en Java

Tengo que imprimir el tiempo EST en mi aplicación Java. Había establecido el huso horario para EST usando:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST")); 

Pero cuando se sigue el horario de verano en esta zona horaria, mi código no imprime la hora correcta (imprime 1 hora menos).

¿Cómo hacer que el código funcione para leer siempre la hora correcta, independientemente de si se cumplen o no los ahorros de luz natural?

PD: intenté configurar la zona horaria para EDT, pero no resuelve el problema.

Este es el problema para comenzar:

 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST")); 

Las abreviaturas de 3 letras deben evitarse de todo corazón a favor de las ID de zona de TZDB. EST es hora estándar del Este – y el tiempo estándar nunca observa horario de verano; no es realmente un nombre de zona horaria completa. Es el nombre utilizado para parte de una zona horaria. (Desafortunadamente, no he encontrado un buen término para este concepto de “zona horaria media”).

Desea un nombre de zona horaria completa . Por ejemplo, America/New_York encuentra en la zona horaria del este:

 TimeZone zone = TimeZone.getTimeZone("America/New_York"); DateFormat format = DateFormat.getDateTimeInstance(); format.setTimeZone(zone); System.out.println(format.format(new Date())); 

Otras respuestas son correctas, especialmente la de Jon Skeet , pero desactualizada.

java.time

Estas antiguas clases de fecha y hora han sido suplantadas por el marco java.time integrado en Java 8 y posterior.

Si simplemente desea la hora actual en UTC, use la clase Instant .

 Instant now = Instant.now(); 

EST no es un huso horario, como se explica en la respuesta correcta de Jon Skeet . Estos códigos de 3-4 letras no están estandarizados ni son únicos, y aumentan la confusión sobre el horario de verano (DST). Use un nombre de zona horaria apropiado en el formato “continente / región”.

¿Quizás te refieres a la hora estándar del Este en la costa este de América del Norte? ¿O el horario estándar de Egipto? ¿O la hora estándar europea?

 ZoneId zoneId = ZoneId.of( "America/New_York" ); ZoneId zoneId = ZoneId.of( "Africa/Cairo" ); ZoneId zoneId = ZoneId.of( "Europe/Lisbon" ); 

Utilice cualquier objeto ZoneId para obtener el momento actual ajustado a una zona horaria particular para producir un objeto ZonedDateTime .

 ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ; 

Ajuste ese ZonedDateTime en un huso horario diferente produciendo otro objeto ZonedDateTime desde el primero. El marco java.time usa objetos inmutables en lugar de cambiar (mutar) objetos existentes.

 ZonedDateTime zdtGuam = zdt.withZoneSameInstant( ZoneId.of( "Pacific/Guam" ) ) ; 

En lugar de ingresar “EST” para la zona horaria, puede ingresar “EST5EDT” como tal. Como notó, solo “EDT” no funciona. Esto explicará el problema del horario de verano. La línea de código se ve así:

 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT")); 

Según esta respuesta :

 TimeZone tz = TimeZone.getTimeZone("EST"); boolean inDs = tz.inDaylightTime(new Date()); 
 public static float calculateTimeZone(String deviceTimeZone) { float ONE_HOUR_MILLIS = 60 * 60 * 1000; // Current timezone and date TimeZone timeZone = TimeZone.getTimeZone(deviceTimeZone); Date nowDate = new Date(); float offsetFromUtc = timeZone.getOffset(nowDate.getTime()) / ONE_HOUR_MILLIS; // Daylight Saving time if (timeZone.useDaylightTime()) { // DST is used // I'm saving this is preferences for later use // save the offset value to use it later float dstOffset = timeZone.getDSTSavings() / ONE_HOUR_MILLIS; // DstOffsetValue = dstOffset // I'm saving this is preferences for later use // save that now we are in DST mode if (timeZone.inDaylightTime(nowDate)) { Log.e(Utility.class.getName(), "in Daylight Time"); return -(ONE_HOUR_MILLIS * dstOffset); } else { Log.e(Utility.class.getName(), "not in Daylight Time"); return 0; } } else return 0; } 

En java, DateFormatter usa de manera predeterminada DST, para evitar el ahorro de luz diurno (DST), debe hacer un truco manualmente,
primero tiene que obtener el desplazamiento de DST, es decir, cuántos DST de milisegundos aplicados, por ejemplo, en algún lugar, el DST también es de 45 minutos y para algunos lugares es de 30 minutos
pero en la mayoría de los casos el horario de verano es de 1 hora
tiene que usar el objeto Zona horaria y verificar con la fecha si está cayendo bajo horario de verano o no y luego tiene que agregar manualmente el desplazamiento de horario de verano en él. por ejemplo:

  TimeZone tz = TimeZone.getTimeZone("EST"); boolean isDST = tz.inDaylightTime(yourDateObj); if(isDST){ int sec= tz.getDSTSavings()/1000;// for no. of seconds Calendar cal= Calendar.getInstance(); cal.setTime(yourDateObj); cal.add(Calendar.Seconds,sec); System.out.println(cal.getTime());// your Date with DST neglected } 

La implementación de la clase TimeZone para configurar la zona horaria en el calendario se ocupa de los ahorros de luz diurna.

java.util.TimeZone representa un desplazamiento de zona horaria, y también calcula los ahorros de luz diurna.

Código de muestra:

 TimeZone est_timeZone = TimeZoneIDProvider.getTimeZoneID(TimeZoneID.US_EASTERN).getTimeZone(); Calendar enteredCalendar = Calendar.getInstance(); enteredCalendar.setTimeZone(est_timeZone); 
    Intereting Posts