4 Stimmen

Java gregoriancalendar um eine Stunde falsch

Ich habe gemacht:

GregorianCalendar gc = new GregorianCalendar(Locale.French);

Und die Stunde ist um eine Stunde falsch. Ich bekomme 14:17 anstatt 15:17. Mein erster Gedanke war die Sommerzeit, aber ich glaube, dass GregorianCalendar das berücksichtigt.

Die Zeit ist auf meinem PC richtig eingestellt.

2voto

bert Punkte 7445

Der Konstruktor, den Sie verwenden, erstellt einen Kalender mit der Standard-Zeitzone (javadoc), dies könnte möglicherweise nicht die korrekte Zeitzone für die angegebene Lokalität sein. Zumindest lese ich das so aus dem Javadoc. Versuchen Sie einen anderen Konstruktor zu verwenden und geben Sie Ihre Zeitzone an.

1voto

Basil Bourque Punkte 256611

Tl;dr

Wie in einem Kommentar erwähnt, haben Sie die Verwendung eines Locale Objekts mit der Angabe einer Zeitzone verwechselt. Ein Locale hat überhaupt nichts mit einer Zeitzone zu tun, und ein Locale beeinflusst nicht die Bedeutung des Datum-Zeit-Werts. Ein Locale beeinflusst nur das Formatieren eines String, der zur Darstellung des Datum-Zeit-Werts verwendet wird.

Kein Locale erforderlich, wenn Sie den aktuellen Moment erfassen. Aber wir brauchen eine Zeitzone.

Instant.now().atZone( ZoneId.of( "America/Montreal" ) )

…oder kurze Version…

ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )

java.time

Sie verwenden problematische alte Legacy-Datum-Zeit-Klassen, die jetzt durch die java.time-Klassen ersetzt wurden.

In UTC arbeiten

Ein Großteil Ihrer Geschäftslogik, Datenablage und Datenaustausch sollte in UTC erfolgen. Denken Sie an UTC als „die eine wahre Zeit“.

Die Instant Klasse stellt einen Zeitpunkt auf der Zeitleiste in UTC mit einer Genauigkeit von Nanosekunden dar.

Instant instant = Instant.now();

Zeitzone angeben

Wie Sie herausgefunden haben, sollten Sie immer die gewünschte/erwartete Zeitzone angeben. Für jeden Moment variieren das Datum und die Tageszeit auf der Welt je nach Zeitzone.

Geben Sie einen richtigen Zeitzonennamen im Format Kontinent/Region an. Verwenden Sie niemals die 3- oder 4-Buchstaben-Abkürzung wie EST oder IST, da sie keine echten Zeitzonen sind, nicht standardisiert und nicht einmal eindeutig(!).

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

Locale angeben

Beachten Sie, dass Zeitzone und Locale eigenständige, völlig separate Themen sind.

  • Die Zeitzone bestimmt die Bedeutung des Datum-Zeit-Werts, wie wir seine Wanduhrzeit betrachten.
  • Das Locale bestimmt (a) die menschliche Sprache für die Übersetzung von Namen des Tages, Namen des Monats und dergleichen und (b) die kulturellen Normen, die Fragen der Abkürzung, Großschreibung, Interpunktion und ähnliches entscheiden.

Dies bedeutet, dass wir jede Zeitzone mit jedem Locale mischen können. Wir können eine Datum-Zeit in der Zone Europe/Paris mit einem Locale von Locale.KOREA haben. Oder eine Zone von Pacific/Auckland mit Locale.CANADA_FRENCH.

Daher wirkt sich Locale nur auf die Darstellung des Datum-Zeit-Werts aus, wie wir eine String-Repräsentation des Datum-Zeit-Werts generieren.

Sie können ein benutzerdefiniertes Formatierungsmuster für die Generierung von Zeichenfolgen angeben. Es ist jedoch besser, java.time automatisch zu lokalisieren.

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
                                       .withLocale( l );
String output = zdt.format( f );

Über java.time

Das java.time Framework ist in Java 8 und später integriert. Diese Klassen ersetzen die problematischen alten Legacy Datum-Zeit-Klassen wie java.util.Date, Calendar & SimpleDateFormat.

Das Joda-Time Projekt, das jetzt im Wartungsmodus ist, empfiehlt die Migration zu den java.time Klassen.

Weitere Informationen finden Sie im Oracle Tutorial. Und suchen Sie auf Stack Overflow nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310.

Wo erhalten Sie die java.time Klassen?

  • Java SE 8, Java SE 9 und später
    • Integriert.
    • Bestandteil der standardmäßigen Java-API mit einer gebündelten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und Java SE 7
    • Viele der java.time-Funktionen sind in Java 6 & 7 mit ThreeTen-Backport zurückportiert.
  • Android
    • Spätere Versionen von Android enthalten Implementierungen der java.time Klassen.
    • Für frühere Android-Versionen passt sich das ThreeTenABP Projekt an ThreeTen-Backport an (oben erwähnt). Siehe Wie man ThreeTenABP benutzt….

Das ThreeTen-Extra Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testgelände für mögliche zukünftige Ergänzungen zu java.time. Hier finden Sie einige nützliche Klassen wie Interval, YearWeek, YearQuarter und mehr.

0voto

Ralph Punkte 114913

Ich bin mir nicht sicher, was du versuchst, aber GregorianCalendar(Locale) basiert immer auf Ihrer Standard-Zeitzone. -- Vielleicht sollten Sie sich GregorianCalendar(TimeZone zone, Locale aLocale) ansehen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X