webentwicklung-frage-antwort-db.com.de

Wie Sie mit TimeZone in Java die Sommerzeit einsparen können

Ich muss die EST-Zeit in meiner Java-Anwendung ausdrucken. Ich hatte die Zeitzone auf EST gesetzt mit:

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

Wenn in dieser Zeitzone die Sommerzeit verwendet wird, gibt mein Code nicht die korrekte Zeit aus (er wird 1 Stunde weniger gedruckt).

Wie lässt sich der Code so einstellen, dass immer die richtige Uhrzeit gelesen wird, unabhängig davon, ob die Sommerzeit gespart wird oder nicht?

PS: Ich habe versucht, die Zeitzone auf EDT einzustellen, aber das Problem wird dadurch nicht gelöst.

54
Surya Chandra

Dies ist das Problem, mit dem ich beginnen möchte:

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

Die aus 3 Buchstaben bestehenden Abkürzungen sollten zu Gunsten der TZDB-Zonen-IDs unbedingt vermieden werden. EST ist Eastern Standard Time - und Standard Time beobachtet niemals DST; Es ist nicht wirklich ein vollständiger Name der Zeitzone. Es ist der Name, der für Teil einer Zeitzone verwendet wird. (Leider habe ich für dieses Konzept der "Halbzeitzone" keinen guten Begriff gefunden.)

Sie möchten einen vollständigen Zeitzone-Namen. Zum Beispiel befindet sich America/New_York in der östlichen Zeitzone:

TimeZone zone = TimeZone.getTimeZone("America/New_York");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);

System.out.println(format.format(new Date()));
104
Jon Skeet

Andere Antworten sind richtig, vor allem die von Jon Skeet , aber veraltet. 

Java.time

Diese alten Datumszeitklassen wurden durch das in Java 8 und höher integrierte Java.time - Framework ersetzt.

Wenn Sie nur die aktuelle Uhrzeit in UTC anzeigen möchten, verwenden Sie die Instant-Klasse.

Instant now = Instant.now();

EST ist keine Zeitzone, wie in der korrekten Antwort von Jon Skeet erläutert. Solche 3-4-Buchstaben-Codes sind weder standardisiert noch eindeutig, und außerdem die Verwirrung über die Sommerzeit (DST). Verwenden Sie einen richtigen Zeitzonennamen im Format "Kontinent/Region".

Vielleicht meinten Sie östliche Standardzeit an der Ostküste Nordamerikas? Oder ägyptische Standardzeit? Oder europäische Normalzeit?

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

Verwenden Sie ein solches ZoneId-Objekt, um das aktuelle Moment an eine bestimmte Zeitzone anzupassen und ein ZonedDateTime - Objekt zu erzeugen.

ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ;

Passen Sie diese ZonedDateTime in eine andere Zeitzone ein, indem Sie ein anderes ZonedDateTime-Objekt vom ersten erstellen. Das Java.time-Framework verwendet unveränderliche Objekte , anstatt vorhandene Objekte zu ändern (zu mutieren).

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

Anstelle von "EST" für die Zeitzone können Sie auch "EST5EDT" eingeben. Wie Sie bemerkt haben, funktioniert "EDT" nicht. Dadurch wird das Problem der Sommerzeit berücksichtigt. Die Codezeile sieht folgendermaßen aus:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT"));
2
Brian N
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;
}
0
fartwhif

Nach dieser Antwort :

TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
0
Daniil Shevelev
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;
}
0
Jackson