Je dois imprimer l'heure EST dans mon application Java. J'avais réglé le fuseau horaire sur EST en utilisant:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
Mais lorsque l'heure d'été est suivie dans ce fuseau horaire, mon code n'imprime pas l'heure correcte (il affiche 1 heure de moins).
Comment faire en sorte que le code fonctionne toujours pour lire l’heure exacte, que l’on observe ou non l’heure avancée?
PS: J'ai essayé de régler le fuseau horaire sur EDT, mais cela ne résout pas le problème.
C'est le problème pour commencer:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
Les abréviations de 3 lettres doivent être évitées de tout cœur en faveur des identifiants de zone TZDB. EST correspond à l'Est Standard Heure - et Standard l'heure n'observe jamais l'heure d'été; ce n'est pas vraiment un nom de fuseau horaire complet. C'est le nom utilisé pour part d'un fuseau horaire. (Malheureusement, je n'ai pas trouvé un bon terme pour ce concept de "demi-fuseau horaire".)
Vous voulez un complet nom du fuseau horaire. Par exemple, America/New_York
est situé dans le fuseau horaire est:
TimeZone zone = TimeZone.getTimeZone("America/New_York");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);
System.out.println(format.format(new Date()));
Les autres réponses sont correctes, notamment celle de Jon Skeet , mais obsolète.
Ces anciennes classes date-heure ont été remplacées par le framework Java.time intégré à Java 8 et versions ultérieures.
Si vous voulez simplement l'heure actuelle en UTC, utilisez la classe Instant
.
Instant now = Instant.now();
EST
n'est pas un fuseau horaire, comme expliqué dans le réponse correcte de Jon Skeet . De tels codes à 3 ou 4 lettres ne sont ni normalisés ni uniques et accentuent la confusion entourant l'heure d'été (DST). Utilisez un nom de fuseau horaire approprié dans le format "continent/région".
Vous vouliez peut-être parler de l'heure normale de l'Est sur la côte est de l'Amérique du Nord? Ou l'heure normale d'Egypte? Ou l'heure standard européenne?
ZoneId zoneId = ZoneId.of( "America/New_York" );
ZoneId zoneId = ZoneId.of( "Africa/Cairo" );
ZoneId zoneId = ZoneId.of( "Europe/Lisbon" );
Utilisez l'un de ces objets ZoneId
pour que le moment actuel soit ajusté à un fuseau horaire particulier afin de générer un objet ZonedDateTime
.
ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ;
Ajustez ce ZonedDateTime dans un fuseau horaire différent en produisant un autre objet ZonedDateTime à partir du premier. Le framework Java.time utilise objets immuables plutôt que de changer (de muter) les objets existants.
ZonedDateTime zdtGuam = zdt.withZoneSameInstant( ZoneId.of( "Pacific/Guam" ) ) ;
Au lieu d'entrer "EST" pour le fuseau horaire, vous pouvez entrer "EST5EDT" en tant que tel. Comme vous l'avez noté, "EDT" ne fonctionne pas. Cela expliquera le problème de l'heure avancée. La ligne de code ressemble à ceci:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT"));
private static Long DateTimeNowTicks(){
long TICKS_AT_Epoch = 621355968000000000L;
TimeZone timeZone = Calendar.getInstance().getTimeZone();
int offs = timeZone.getRawOffset();
if (timeZone.inDaylightTime(new Date()))
offs += 60 * 60 * 1000;
return (System.currentTimeMillis() + offs) * 10000 + TICKS_AT_Epoch;
}
Selon cette réponse :
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;
}