18 Stimmen

Konvertierung einer Zeichenkette in GregorianCalendar

Ich habe eine Zeichenfolge aus einer E-Mail-Kopfzeile, wie Date: Mon, 27 Oct 2008 08:33:29 -0700 . Was ich brauche, ist eine Instanz von GregorianCalendar, die denselben Zeitpunkt darstellt. So einfach wie das - wie mache ich es?

Und für die Schnellsten - das ist no richtig funktionieren wird:

SimpleDateFormat format = ... // whatever you want
Date date = format.parse(myString)
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(date)

denn es normalisiert die Zeitzone auf UTC (oder Ihre lokale Rechnerzeit, je nach Java-Version). Was ich brauche, ist calendar.getTimeZone().getRawOffset(), um Folgendes zurückzugeben -7 * milisInAnHour .

15voto

Jack Leow Punkte 21300

Ich würde empfehlen, sich die Joda Time-Bibliothek anzuschauen, falls das eine Option ist. Normalerweise bin ich gegen die Verwendung einer Bibliothek eines Drittanbieters, wenn die Kernplattform eine ähnliche Funktionalität bietet, aber ich habe hier eine Ausnahme gemacht, weil der Autor von Joda Time auch hinter JSR310 steht und Joda Time im Grunde genommen irgendwann in Java 7 integriert werden soll.

http://joda-time.sourceforge.net/

Wenn Joda Time also eine Option ist, dann etwa so sollte Arbeit:

DateTimeFormatter formatter =
    DateTimeFormat.forPattern("your pattern").withOffsetParsed();
DateTime dateTime = formatter.parseDateTime("your input");
GregorianCalendar cal = dateTime.toGregorianCalendar();

Ich hoffe, das hilft.

6voto

matt b Punkte 135206

Und für die Schnellsten - das wird nicht richtig funktionieren ... denn es normalisiert die Zeitzone auf UTC (oder Ihre lokale Rechnerzeit, je nach Java-Version). Was ich brauche ist calendar.getTimeZone().getRawOffset() um -7 * milisInAnHour zurückzugeben.

Nun, technisch gesehen funktioniert das, denn es wird zwar ein Objekt mit TimeZone zurückgegeben, das der aktuellen System TimeZone entspricht, aber die Zeit wird geändert, um die Verschiebung zu berücksichtigen.

Dieser Code:

String dateString = "Mon, 27 Oct 2008 08:33:29 -0700";
DateFormat df = new SimpleDateFormat("E, dd MMM yyyy hh:mm:ss Z");
Date parsed = df.parse(dateString);
System.out.println("parsed date: " + parsed);

Calendar newCalendar = Calendar.getInstance();
newCalendar.setTime(parsed);

Ausgänge:

geparst Datum: Mon Oct 27 11:33:29 EDT 2008

was technisch gesehen korrekt ist, da meine Systemzeitzone EDT / UTC minus vier Stunden ist (und damit drei Stunden vor der Ihren). Wenn Sie die Zeit als die Anzahl der Millisekunden seit dem 1. Januar 1970, 00:00:00 GMT, ausdrücken (das ist die Art, wie die Date Objekt sein Datum/Uhrzeit speichert), dann sind diese Daten/Uhrzeiten gleich, nur die TimeZone ist unterschiedlich.

Ihr Thema ist wirklich Wie kann ich ein Datum/Kalender in meine Zeitzone umwandeln? Sehen Sie sich dazu meine Antwort auf die vorherige Frage an Wie kann man Kalender-Zeitzonen mit Java handhaben?

3voto

Arvind Kumar Avinash Punkte 62339

java.time

Lösung mit java.time die moderne Datum-Zeit-API :

Die moderne Datums-Zeit-API bietet OffsetDateTime um ein Datum-Zeit-Objekt mit einem Zeitzonen-Offset darzustellen. Es kann konvertiert werden in Instant der einen momentanen Punkt auf der Zeitachse darstellt. Eine Instant ist unabhängig von der Zeitzone, d. h. sie hat einen Zeitzonen-Offset von +00:00 Stunden, bezeichnet als Z dans le ISO 8601 Normen.

Instant#toEpochMilli wandelt diesen Zeitpunkt in die Anzahl der Millisekunden ab der Epoche 1970-01-01T00:00:00Z um. Dieser Wert kann in ein Objekt von GregorianCalendar die dann denselben Zeitpunkt darstellen.

Demo:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Mon, 27 Oct 2008 08:33:29 -0700";
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime, DateTimeFormatter.RFC_1123_DATE_TIME);
        System.out.println(odt);

        // In case you want a time zone neutral object, convert to Instant
        Instant instant = odt.toInstant();
        System.out.println(instant);

        // Edit: If the requirement is a GregorianCalendar having the offset from
        // the string — typically for an old API not yet upgraded to java.time: 
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, DateTimeFormatter.RFC_1123_DATE_TIME);
        GregorianCalendar gc = GregorianCalendar.from(zdt);

        System.out.println("As Date:      " + gc.getTime());
        System.out.println("Time zone ID: " + gc.getTimeZone().getID());
        System.out.println("Hour of day:  " + gc.get(Calendar.HOUR_OF_DAY));
        // ...
    }
}

Ausgabe:

2008-10-27T08:33:29-07:00
2008-10-27T15:33:29Z
As Date:      Mon Oct 27 15:33:29 GMT 2008
Time zone ID: GMT-07:00
Hour of day:  8

Aufruf von getTime() en el GregorianCalendar wandelt sich in eine Date (eine weitere alte und fehleranfällige Klasse), die keine Zeitzone hat, so dass der Offset verloren geht. Das Ausdrucken der Zeitzonen-ID und der Tageszeit zeigt, dass sowohl der Zeitversatz als auch die Tageszeit in der Klasse GregorianCalendar .

Erfahren Sie mehr über die moderne Datums-Zeit-API von Pfad: Datum Uhrzeit .


* Wenn Sie aus irgendeinem Grund bei Java 6 oder Java 7 bleiben müssen, können Sie DreiZehn-Backport das den größten Teil der java.time Funktionalität für Java 6 und 7. Wenn Sie an einem Android-Projekt arbeiten und Ihr Android-API-Level noch nicht mit Java-8 übereinstimmt, prüfen Sie Java 8+ APIs verfügbar durch Desugaring et Wie man ThreeTenABP in einem Android-Projekt verwendet .

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