So bewältigen Sie die Sommerzeit mit TimeZone in Java

Lesezeit: 9 Minuten

So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Surya Chandra

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

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

Aber wenn die Sommerzeit in dieser Zeitzone eingehalten wird, gibt mein Code nicht die richtige Zeit aus (er druckt 1 Stunde weniger).

Wie kann der Code dazu gebracht werden, immer die richtige Zeit zu lesen, unabhängig davon, ob die Sommerzeit eingehalten wird oder nicht?

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

  • Könnten Sie Ihren Beispielcode erweitern und genau zeigen, was Sie versuchen?

    – Sebastian

    11. Mai ’12 um 5:39 Uhr


  • Ich mache nicht viel damit, außer dass ich das Datum drucke. Aber wenn ich die Stunde in der Ausgabe sehe, wird sie falsch angezeigt (1 Stunde weniger), wenn in EST die Sommerzeit eingehalten wird. Wie man sich um die Sommerzeit kümmert, ist meine Frage

    – Surya Chandra

    11. Mai ’12 um 5:45 Uhr

  • Bitte bearbeiten Sie Ihre Frage mit diesen Informationen. Es könnte in den Kommentaren übersehen werden, aber wahrscheinlich nicht in Ihrer Frage. Bearbeiten und präzisieren Sie diese Aussage bitte auch PS: I tried setting the timezone to EDT, but it solve the problem

    – David

    11. Mai 12 um 5:47 Uhr

  • Die Sommerzeit stellt die Uhren zu Beginn der Sommerzeit um eine Stunde vor und am Ende um den gleichen Betrag zurück. Das Verhalten, das Sie sehen, ist meiner Meinung nach völlig normal. Bitte durchgehen en.wikipedia.org/wiki/Daylight_saving_time

    – Alle

    11. Mai 12 um 5:52 Uhr


  • “wenn Sommerzeit in EST folgt” – Sie meinen “wenn Sommerzeit in Eastern Time folgt”. EST ist östlich Standard Zeit – wo Standard ist das Gegenteil von Tageslicht.

    – Jon Skeet

    11. Mai 2012 um 5:54 Uhr

Das ist das Problem zu Beginn:

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

Die 3-Buchstaben-Abkürzungen sollten zugunsten von TZDB-Zonen-IDs von ganzem Herzen vermieden werden. EST ist östlich Standard Zeit und Standard die Zeit beachtet nie die Sommerzeit; es ist nicht wirklich ein vollständiger Zeitzonenname. Es ist der Name für verwendet Teil einer Zeitzone. (Leider ist mir kein passender Begriff für dieses „halbe Zeitzone“-Konzept begegnet.)

Du willst ein voll Name der Zeitzone. Beispielsweise, America/New_York liegt 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()));

  • Danke @Jon, ist es möglich, das Format dann mit so etwas zu ändern DateFormat format = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy").getDateTimeInstance()? Mein Beispiel generiert die Warnung “Auf die statische Methode getDateTimeInstance() vom Typ DateFormat sollte statisch zugegriffen werden“.

    – IanCampbell

    11. Oktober 13 um 13:36 Uhr

  • @IanCampbell: Es ist überhaupt nicht klar, was Sie davon erwarten würden – es ist eine statische Methode, also würden Sie normalerweise nur verwenden DateFormat format = DateFormat.getDateTimeInstance(). Es ist eine statische Methode, hat also nichts mit einer vorhandenen Instanz zu tun. Es ist wirklich unklar, was Sie zu tun versuchen, aber Sie sollten wahrscheinlich eine neue Frage stellen.

    – Jon Skeet

    11. Oktober 13 um 14:39 Uhr

  • Ok, danke @Jon, ich frage mich nur, wie ich das Ausgabeformat ändern kann in “HH:mm:ss:ms MM/dd/yyyy“.

    – IanCampbell

    11. Oktober 13 um 16:11 Uhr

  • Entschuldigung für die Verwirrung @Jon, ich habe gerade getan, was Sie vorgeschlagen haben: SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy"); System.out.println(format.format(new Date())); … Ersetzen der letzten Codezeile aus der Antwort, um die gewünschte Ausgabe zu erhalten. Danke für die Hilfe.

    – IanCampbell

    11. Oktober 13 um 21:32 Uhr


  • @maximus: Ich bin mir nicht sicher, was du damit meinst. Das Ergebnis von new Date() stützt sich nicht auf die Systemzeitzone. Wenn Sie meinen, Sie würden verwenden SimpleDateFormat mit der systemzeitzone, dann ja, anrufen sdf.format(new Date()); und dann sofort sdf.format(new Date()); ein paar Millisekunden später kann zu Zeichenfolgendarstellungen führen, die scheinbar eine Stunde auseinander liegen.

    – Jon Skeet

    14. März 16 um 12:04 Uhr


So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Basil Bourque

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

java.time

Diese alten Datums-/Uhrzeitklassen wurden durch die ersetzt java.time Framework, das in Java 8 und höher integriert ist.

Wenn Sie einfach die aktuelle Zeit in UTC wollen, verwenden Sie die Instant Klasse.

Instant now = Instant.now();

EST ist keine Zeitzone, wie in der richtigen Antwort von Jon Skeet erklärt. Solche 3-4-Buchstaben-Codes sind weder standardisiert noch eindeutig und fördern die Verwirrung über die Sommerzeit (DST). Verwenden Sie einen korrekten Zeitzonennamen im Format “Kontinent/Region”.

Vielleicht meinten Sie Eastern Standard Time 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 solche ZoneId Objekt, um den aktuellen Moment an eine bestimmte Zeitzone anzupassen, um a zu erzeugen ZonedDateTime Objekt.

ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ;

Passen Sie diese ZonedDateTime an eine andere Zeitzone an, indem Sie ein weiteres ZonedDateTime-Objekt aus dem ersten erstellen. Das java.time-Framework verwendet unveränderliche Objekte anstatt bestehende Objekte zu verändern (zu mutieren).

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

Tabelle der Datums- und Uhrzeittypen in Java, sowohl modern als auch veraltet.

  • Ein Instant ist nicht dasselbe wie eine Zeit in UTC. Letztere können beispielsweise Schaltsekunden haben.

    – Orangenhund

    13. April 17 um 10:17 Uhr


  • @OrangeDog Wenn ein Instant als Datum und Uhrzeit wahrgenommen wird, dann werden Schaltsekunden irrelevant. Das ist der springende Punkt bei Schaltsekunden, um unsere Uhren einen Moment anzuhalten, damit unser Kalender mit der allgemein langsamer werdenden astronomischen Position der Erde synchronisiert wird. Es stimmt zwar die interne Darstellung von Instant ist kurz durch die Anzahl der Schaltsekunden, die bisher deklariert wurden (eine alle paar Jahre oder so), diese Unterscheidung ist strittig, wenn Datum und Uhrzeit diskutiert werden. Diese Details werden in der Klassendokumentation für diejenigen besprochen, die sich dafür interessieren. Fazit: Praktisch gesehen, Instant ist UTC.

    – Basilikum Bourque

    13. April 17 um 15:44 Uhr


  • Oh nein. Eine UTC-Schaltsekunde “stoppt die Uhr nicht”, sie fügt eine weitere Sekunde hinzu (2016-12-24T23:23:60Z ist die neueste). Die Java-Zeit, dargestellt durch Instant stoppt die Uhr auch nicht – sie hat an diesem Tag die gleiche Anzahl von Millisekunden, aber sie waren alle etwas länger. Auch wenn Sie das nicht so sehen wollen, ist es doch so implementiert, weshalb Sie z. B. keine formatieren können Instant verwenden ISO_DATE_TIME.

    – Orangenhund

    13. April 17 um 15:47 Uhr


  • Glücklicherweise ist der Umbau einfach – Instant.now().atZone(ZoneOffset.UTC)

    – Orangenhund

    13. April 17 um 15:52 Uhr

  • Das Hinzufügen einer Sekunde stoppt tatsächlich die Uhr in Bezug auf Datum und Uhrzeit. Wir nehmen uns einen zusätzlichen Moment, bevor wir zum nächsten Datum im Kalender übergehen. Und so wird eine Schaltsekunde von unserem Kalender absorbiert. Wie ich schon sagte, das ist der springende Punkt bei Schaltsekunden: Verlangsamen Sie unsere Uhren, um unsere Kalenderverfolgung zu verlangsamen. Während Ihr Argument zum Ignorieren von Schaltsekunden in Bezug auf die interne Darstellung der java.time-Klassen technisch korrekt ist, ist Ihr Argument in praktischer Hinsicht irrelevant, pedantisch und unnötig verwirrend für die vielen Programmierer, die Schwierigkeiten haben, zu lernen, wie man Datums- und Uhrzeitangaben darstellt.

    – Basilikum Bourque

    13. April 17 um 15:59 Uhr


1644071289 994 So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Brian N

Anstatt “EST” für die Zeitzone einzugeben, können Sie “EST5EDT” als solche eingeben. Wie Sie bemerkt haben, funktioniert nur “EDT” nicht. Dies wird das Problem der Sommerzeit berücksichtigen. Die Codezeile sieht so aus:

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

1644071289 943 So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Daniil Shevelev

Gemäß dieser Antwort:

TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());

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;
}

  • Diese schrecklichen alten Date-Time-Klassen wurden vor Jahren durch die verdrängt java.time Klassen mit der Einführung von JSR 310. Diese Legacy-Klassen sollten überhaupt nicht mehr verwendet werden.

    – Basilikum Bourque

    15. Oktober 18 um 16:40 Uhr


  • Manchmal wird ein Entwickler in eine schreckliche alte Legacy-Situation gezwungen, aber gut zu wissen, danke.

    – Furz

    24. Oktober 18 um 15:01 Uhr


  • Für Java 6 und Java 7 sind die meisten java.time Die Funktionalität wird mit nahezu identischer API in der zurückportiert ThreeTen-Backport Projekt. Es besteht also wirklich keine Notwendigkeit, jemals die schrecklichen veralteten Datums-Zeit-Klassen wie z Date, Calendar, SimpleDateFormat.

    – Basilikum Bourque

    24. Oktober 18 um 15:50 Uhr


  • Manchmal wird ein Entwickler ohne Backport in eine schreckliche alte Legacy-Situation gezwungen und hat daher keine andere Wahl, als die schrecklichen Legacy-Date-Time-Klassen zu verwenden, aber gut zu wissen, danke!

    – Furz

    25. Oktober 18 um 17:06 Uhr


1644071290 75 So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Jayesh Kalkani

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;
}

  • Diese schrecklichen alten Date-Time-Klassen wurden vor Jahren durch die verdrängt java.time Klassen mit der Einführung von JSR 310. Diese Legacy-Klassen sollten überhaupt nicht mehr verwendet werden.

    – Basilikum Bourque

    15. Oktober 18 um 16:40 Uhr


  • Manchmal wird ein Entwickler in eine schreckliche alte Legacy-Situation gezwungen, aber gut zu wissen, danke.

    – Furz

    24. Oktober 18 um 15:01 Uhr


  • Für Java 6 und Java 7 sind die meisten java.time Die Funktionalität wird mit nahezu identischer API in der zurückportiert ThreeTen-Backport Projekt. Es besteht also wirklich keine Notwendigkeit, jemals die schrecklichen veralteten Datums-Zeit-Klassen wie z Date, Calendar, SimpleDateFormat.

    – Basilikum Bourque

    24. Oktober 18 um 15:50 Uhr


  • Manchmal wird ein Entwickler ohne Backport in eine schreckliche alte Legacy-Situation gezwungen und hat daher keine andere Wahl, als die schrecklichen Legacy-Date-Time-Klassen zu verwenden, aber gut zu wissen, danke!

    – Furz

    25. Oktober 18 um 17:06 Uhr


So bewaltigen Sie die Sommerzeit mit TimeZone in Java
Sunil Garg

In Java verwendet DateFormatter standardmäßig die Sommerzeit. Um die Sommerzeit (DST) zu vermeiden, müssen Sie manuell einen Trick ausführen.
Zuerst müssen Sie den DST-Offset erhalten, dh für wie viele Millisekunden DST angewendet wird, zum Beispiel gilt die DST irgendwo auch für 45 Minuten und für einige Orte für 30 Minuten
aber in den meisten Fällen beträgt die Sommerzeit 1 Stunde
Sie müssen das Timezone-Objekt verwenden und anhand des Datums prüfen, ob es unter die Sommerzeit fällt oder nicht, und dann müssen Sie den Offset der Sommerzeit manuell hinzufügen. für zB:

 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
  }

  • Das war tatsächlich hilfreich – ich musste ein Datum “aufheben” und war mir der Funktion “inDayLightTime” nicht bewusst. Danke!

    – David

    22. Mai 20 um 13:26 Uhr

.

784220cookie-checkSo bewältigen Sie die Sommerzeit mit TimeZone in Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy