Frage

Ich habe den folgenden Code, der eine Reihe von Millisekunden nimmt (stammt aus einem RSS -Feed.

public static void main(String[] args) {
    String ms = "1302805253";
    SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(Long.parseLong(ms));

    try {
        String dateFormat = dateFormatter.format(calendar.getTime());
        System.out.println("Date Format = " + dateFormat);

        Date dateParse = dateFormatter.parse(dateFormatter.format(calendar.getTime()));
        System.out.println("Date Parse  = " + dateParse);
    } catch (ParseException e) {
        // TODO: handle exception
    }
}


Output:
    Date Format = Fri, 16 Jan 1970 02:53:25 GMT
    Date Parse  = Fri Jan 16 03:53:25 GMT 1970

Wie Sie sehen können, geht zwischen der Formatierung des Kalenderobjekts und der Parsen der resultierenden Zeichenfolge eine Stunde verloren. Auch die Formatierung der Ausgabe hat sich geändert. Kann mir jemand helfen, warum dies passiert und wie ich es umhergehen kann? Ich möchte, dass das Datumsobjekt das gleiche Format wie die Ausgabe "Datumsformat" ist.

War es hilfreich?

Lösung

Ich glaube, es passiert, weil Großbritannien es nicht getan hat eigentlich Verwenden Sie GMT im Jahr 1970, und Java hat einen Fehler darum ... es wird es wird Format Ein Datum im Jahr 1970, als würde das Vereinigte Königreich GMT verwenden, ohne den Offset tatsächlich zu ändern. Einfaches Beispiel:

Date date = new Date(0);
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss zzz");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(sdf.format(date));

Ergebnis:

01 Jan 1970 01:00:00 GMT

Beachten Sie, dass es 1 Uhr GMT ist ... was falsch ist. Es war 1 Uhr morgens in Europa/London, aber Europa/London beobachtete GMT nicht.

Joda -Zeit bekommt das richtig darin, dass es BST ausdruckt - aber Joda Time mag es nicht Parsing Werte mit Zeitzonenabkürzungen. Sie können es jedoch dazu bringen, die Zeitzone zu verwenden Offets stattdessen:

import org.joda.time.*;
import org.joda.time.format.*;

public class Test {
    public static void main(String[] args) throws Exception {
        DateTime date = new DateTime(0, DateTimeZone.forID("Europe/London"));

        DateTimeFormatter formatter = DateTimeFormat.forPattern(
            "dd MMM yyyy HH:mm:ss Z");

        String text = formatter.print(date); // 01 Jan 1970 01:00:00 +0100
        System.out.println(text);

        DateTime parsed = formatter.parseDateTime(text);
        System.out.println(parsed.equals(date)); // true
    }
}

Andere Tipps

Das Antwort von Jon Skeet ist richtig.

Java.Time

Lassen Sie uns dieselbe Eingabe über Java -Time ausführen, um die Ergebnisse zu sehen.

Angeben a richtiger Zeitzonenname. Verwenden Sie niemals die 3-4-Buchstabenabkürzung wie z. BST, EST, oder IST da sie keine wahren Zeitzonen sind, nicht standardisiert und nicht einmal einzigartig (!). Also benutzen wir Europe/London.

Das Instant Die Klasse repräsentiert einen Moment auf der Zeitleiste in koordinierte Weltzeit mit einer Lösung von Nanosekunden.

String input = "1302805253";
long millis = Long.parseLong ( input );
Instant instant = Instant.ofEpochMilli ( millis );

Wenden Sie eine Zeitzone an, um a zu erzeugen ZonedDateTime Objekt.

ZoneId zoneId = ZoneId.of ( "Europe/London" );
ZonedDateTime zdt = instant.atZone ( zoneId );

Dump zu Konsole. Wir sehen das in der Tat Europe/London Die Zeit ist in diesem Moment eine Stunde vor UTC. Der Tageszeit ist also 02 Stunden und nicht 01 Std. Beide repräsentieren denselben gleichzeitigen Moment auf der Zeitleiste, die gerade durch die Objektive von zwei verschiedenen betrachtet wurde Wandverrückte.

System.out.println ( "input: " + input + " | instant: " + instant + " | zdt: " + zdt );

Eingabe: 1302805253 | Instant: 1970-01-16T01: 53: 25.253z | ZDT: 1970-01-16T02: 53: 25.253+01: 00 [Europa/London

Ganze Sekunden

Übrigens vermute ich, dass Ihre Eingangszeichenfolge repräsentiert ganz Sekunden seit der Epoche von 1970 UTC und nicht seit der EPOCHE Millisekunden. Interpretierte, dass wir als Sekunden 2011 ein Datum im Monat in dem Monat erhalten, in dem diese Frage veröffentlicht wurde.

String output = Instant.ofEpochSecond ( Long.parseLong ( "1302805253" ) ).atZone ( ZoneId.of ( "Europe/London" ) ).toString ();

2011-04-14t19: 20: 53+01: 00 [Europa/London

Über Java.Time

Das Java.Time Das Rahmen ist in Java 8 und später in eingebaut. Diese Klassen ersetzen die alten störenden Datumszeitklassen wie z. java.util.Date, .Calendar, & java.text.SimpleDateFormat.

Das Joda-Zeit Projekt jetzt in Wartungsmodus, rät die Migration zu Java.Time.

Um mehr zu erfahren, sehen Sie die Oracle Tutorial. Und Suchstapelüberlauf für viele Beispiele und Erklärungen.

Ein Großteil der Java. TreeTen-backport und weiter angepasst an Android in TreeTenabp.

Das Treetren-extra Das Projekt erweitert Java.Time mit zusätzlichen Klassen. Dieses Projekt ist ein nachweisender Grund für mögliche zukünftige Ergänzungen zu Java.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top