Das Konvertieren von Long in Date in Java gibt 1970 zurück

Ich habe Liste mit langen Werten (zum Beispiel: 1220227200, 1220832000, 1221436800 …), die ich vom Web-Service heruntergeladen habe. Ich muss es in Daten konvertieren. Leider auf diese Weise, zum Beispiel:

Date d = new Date(1220227200); 

Gibt 1 Jan 1970 zurück. Wer weiß einen anderen Weg, um es richtig zu konvertieren?

Solutions Collecting From Web of "Das Konvertieren von Long in Date in Java gibt 1970 zurück"

Der Date Konstruktor (klicken Sie auf den Link!) Akzeptiert die Zeit so long in Millisekunden , nicht in Sekunden. Sie müssen es mit 1000 multiplizieren und sicherstellen, dass Sie es so long liefern.

 Date d = new Date(1220227200L * 1000); 

Dies zeigt sich hier

So Aug 31 20:00:00 GMT-04: 00 2008

tl; dr

 Instant.ofEpochSecond( 1_220_227_200L ) 

Kenne deine Daten

Leute benutzen verschiedene Präzision in der Nachverfolgungszeit als eine Zahl seit einer Epoche . Wenn Sie also seit einer Epoche Zahlen erhalten, die als Zahl interpretiert werden, müssen Sie Folgendes bestimmen:

  • Welche Epoche?
    Viele Epochen wurden in verschiedenen Systemen verwendet. Üblicherweise wird POSIX / Unix-Zeit verwendet , wobei die Epoche der erste Moment von 1970 in UTC ist. Aber Sie sollten diese Epoche nicht annehmen .
  • Welche Präzision?
    Sprechen wir seit der Epoche über Sekunden, Millisekunden , Mikrosekunden oder Nanosekunden ?
  • Welche Zeitzone?
    Normalerweise liegt eine Zählung seit der Epoche in der UTC / GMT-Zeitzone, das heißt, sie hat überhaupt keine Zeitzonenverschiebung. Aber manchmal, wenn unerfahrene oder Datum-Zeit ignorierende Programmierer beteiligt sind, kann es eine implizierte Zeitzone geben.

In Ihrem Fall, wie andere bereits angemerkt haben, scheinen Ihnen seit der Unix-Epoche Sekunden gegeben worden zu sein. Aber Sie geben diese Sekunden an einen Konstruktor weiter, der Millisekunden erwartet. Also ist die Lösung, um 1000 zu multiplizieren.

Gewonnene Erkenntnisse:

  • Bestimmen Sie, nehmen Sie nicht an, die Bedeutung der empfangenen Daten.
  • Lesen Sie das Dokument .

Graph, der verschiedene Granularitäten der Auflösung in Datum-Zeit-Systemen zeigt, einschließlich ganzer Sekunden, Millisekunden, Mikrosekunden und Nanosekunden.

Deine Daten

Ihre Daten scheinen in Sekunden zu liegen. Wenn wir von einer Epoche Anfang 1970 ausgehen und die UTC – Zeitzone annehmen, dann ist 1,220,227,200 der erste Moment des ersten Septembertages 2008.

Joda-Zeit

Die Java-classn java.util.Date und .Calendar sind bekanntermaßen mühsam. Vermeide sie. Verwenden Sie stattdessen entweder die Joda-Time- Bibliothek oder das neue java.time-Paket, das in Java 8 gebündelt ist (und von Joda-Time inspiriert wurde).

Beachten Sie, dass eine DateTime in Joda-Time im Gegensatz zu juDate ihre eigene zugewiesene Zeitzone wirklich kennt. In dem Beispiel Joda-Time 2.4 Code, der unten zu sehen ist, beachten Sie, dass wir zuerst die Millisekunden unter Verwendung der Standardannahme von UTC analysieren. Dann ordnen wir zweitens eine Zeitzone von Paris zu, um sie anzupassen. Derselbe Moment in der Zeitlinie des Universums, aber unterschiedliche Wanduhrzeiten . Zur Demonstration stellen wir uns wieder auf UTC ein. Es ist fast immer besser, die gewünschte / erwartete Zeitzone explizit anzugeben, statt sich auf einen impliziten Standard zu verlassen (was häufig die Ursache für Probleme bei der Datums- / Uhrzeit-Arbeit ist).

Wir benötigen Millisekunden, um eine DateTime zu erstellen. Nimm also deine Eingabe von Sekunden und multipliziere sie mit tausend. Beachten Sie, dass das Ergebnis 64 Bit long da wir einen 32-Bit- int überlaufen würden.

 long input = 1_220_227_200L; // Note the "L" appended to long integer literals. long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L". 

Feed die Anzahl der Millisekunden zum Konstruktor. Dieser bestimmte Konstruktor geht davon aus, dass die Zählung aus der Unix-Epoche von 1970 stammt. Passen Sie daher die Zeitzone nach der Konstruktion wie gewünscht an.

Verwenden Sie die richtigen Zeitzonennamen , eine Kombination aus Kontinent und Stadt / Region. Verwenden Sie niemals 3- oder 4-stellige Codes wie EST da sie weder standardisiert noch eindeutig sind.

 DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) ); 

Stellen Sie die Zeitzone zur Demonstration erneut ein.

 DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC ); DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) ); 

Dump zur Konsole. Beachten Sie, dass das Datum in Montréal anders ist, da der neue Tag in Europa begonnen hat, aber noch nicht in Amerika.

 System.out.println( "dateTimeParis: " + dateTimeParis ); System.out.println( "dateTimeUTC: " + dateTimeUtc ); System.out.println( "dateTimeMontréal: " + dateTimeMontréal ); 

Wenn ausgeführt.

 dateTimeParis: 2008-09-01T02:00:00.000+02:00 dateTimeUTC: 2008-09-01T00:00:00.000Z dateTimeMontréal: 2008-08-31T20:00:00.000-04:00 

java.time

Die Macher von Joda-Time haben uns gebeten, sobald wie möglich zu ihrem Ersatz, dem java.time Framework, zu wechseln . Während Joda-Time weiterhin aktiv unterstützt wird, wird die gesamte zukünftige Entwicklung in den java.time-classn und deren Erweiterungen im ThreeTen-Extra-Projekt erfolgen.

Das Java-Zeit-Framework wird von JSR 310 definiert und in Java 8 und höher eingebaut. Die classn java.time wurden im ThreeTen-Backport- Projekt auf Java 6 & 7 und im ThreeTenABP- Projekt auf Android portiert .

Ein Instant ist ein Moment auf der Timeline in UTC mit einer Auflösung von Nanosekunden. Seine Epoche ist der erste Moment von 1970 in UTC.

 Instant instant = Instant.ofEpochSecond( 1_220_227_200L ); 

Wenden Sie einen Offset-from-UTC ZoneOffset an, um eine OffsetDateTime .

Besser noch, falls bekannt, wenden Sie eine ZoneId Zeitzone an, um eine ZonedDateTime .

 ZoneId zoneId = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); 

Es sieht so aus, als wären Ihre Longs Sekunden und nicht Millisekunden. Der Datumskonstruktor braucht Zeit als Millis, also

 Date d = new Date(timeInSeconds * 1000); 

Dies sind wahrscheinlich Zeitstempel in Sekunden und nicht in Millisekunden, die für den neuen Java-Konstruktor Date (long) benötigt werden. Multiplizieren Sie sie einfach mit 1000 und Sie sollten in Ordnung sein.

Legen Sie nur die Uhrzeit in Mühlen für das Kalenderobjekt fest

 Calendar c = Calendar.getInstance(); c.setTimeInMillis(1385355600000l); System.out.println(c.get(Calendar.YEAR)); System.out.println(c.get(Calendar.MONTH)); System.out.println(c.get(Calendar.DAY_OF_MONTH)); // get Date System.out.println(c.getTime()); 

Versuche dies:

 Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(1220227200 * 1000); System.out.println(cal.getTime()); 

Die langen Werte entsprechen höchstwahrscheinlich Epochen- Zeitstempeln und die Werte sind:

1220227200 = Mo, 01 Sep 2008 00:00:00 GMT

1220832000 = Montag, 08. September 2008 00:00:00 GMT

1221436800 = Mo, 15 Sep 2008 00:00:00 GMT

Man kann diese langen Werte in java.util.Date konvertieren, wobei man berücksichtigt, dass java.util.Date Millisecs verwendet – wie zuvor angedeutet, aber mit einem Fehler – wie folgt:

 // note: enforcing long literals (L), without it the values would just be wrong. Date date = new Date(1220227200L * 1000L); 

Um nun das Datum korrekt anzuzeigen, kann man java.text.DateFormat wie folgt verwenden:

 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); df.setTimeZone(TimeZone.getTimeZone("UTC")); System.out.println("Wrong date time value: " + date); System.out.println("Correct date time value: " + df.format(date)); 

Im Folgenden finden Sie die Ergebnisse der Anzeige des konvertierten Langwerts in java.util.Date, ohne das DateFormat zu verwenden und zu verwenden:

 Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008 Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC 

1220227200 entspricht dem 15. Januar 1980 (und tatsächlich dem neuen Datum (1220227200) .toString () gibt “Do Jan 15 03:57:07 CET 1970” zurück). Wenn Sie einen langen Wert an ein Datum übergeben, das vor dem 01.01.1970 liegt, wird in der Tat ein Datum vom 01.01.1970 zurückgegeben. Stellen Sie sicher, dass Ihre Werte nicht in dieser Situation sind (niedriger als 82800000).

Neues Datum (Zahl) gibt ein Datum zurück, das die number Millisekunden nach dem 1. Januar 1970 ist. Die Wahrscheinlichkeit ist, dass das Datumsformat Stunden, Minuten und Sekunden nicht anzeigt, damit Sie sehen, dass es nur ein kleines bisschen nach dem 1. Januar 1970 ist.

Sie müssen das Datum gemäß dem richtigen Parsing-Routing analysieren. Ich weiß nicht, was ein 1220227200 ist, aber wenn es Sekunden nach dem 1. Januar 1970 ist, dann multipliziere es, um Millisekunden zu ergeben. Wenn dies nicht der Fall ist, wandeln Sie es nach 1970 in Millisekunden um (wenn Sie java.util.Date weiterhin verwenden möchten).

functioniert bei mir. Vermutlich willst du es mit 1000 multiplizieren, denn du erhältst die Sekunden von 1970 und musst die Millisekunden vom 1. Januar 1970 durchgehen