Java: Datum vom Unix-Zeitstempel

237

Ich muss einen Unix-Zeitstempel in ein Datumsobjekt konvertieren.
Ich habe es versucht:

java.util.Date time = new java.util.Date(timeStamp);

Der Zeitstempelwert ist: 1280512800

Das Datum sollte "30.07.2010 - 22:30:00" sein (wie ich es von PHP bekomme), aber stattdessen bekomme ich Thu Jan 15 23:11:56 IRST 1970.

Wie soll es gemacht werden?

RYN
quelle
2
Wenn Sie Java 8 oder neuer: Haben Sie einen Blick auf diese Antwort: stackoverflow.com/a/24703644/1115554
micha
1
Zu Ihrer Information , die problematischen alten Datums- / Uhrzeitklassen, wie sie java.util.Datejetzt Legacy sind , werden durch die Klassen java.time ersetzt . Siehe Tutorial von Oracle .
Basil Bourque

Antworten:

429

Für 1280512800, multipliziert mit 1000, da Java erwartet Millisekunden:

java.util.Date time=new java.util.Date((long)timeStamp*1000);

Wenn Sie bereits Millisekunden hatten, dann nur new java.util.Date((long)timeStamp);

Aus der Dokumentation :

Weist ein Date-Objekt zu und initialisiert es so, dass es die angegebene Anzahl von Millisekunden seit der als "Epoche" bekannten Standardbasiszeit darstellt, nämlich 1. Januar 1970, 00:00:00 GMT.

Pablo Santa Cruz
quelle
40
Die Besetzung (long)ist sehr wichtig: Ohne sie läuft die ganze Zahl über.
Mneri
2
@TomasK java.util.Dateist der vollständig qualifizierte Name der Klasse. Dateist wahrscheinlich genau das Gleiche, vorausgesetzt, Sie importieren das java.utilPaket in Ihre Klasse.
Pablo Santa Cruz
5
Die Besetzung zu lang wird nicht benötigt. time = new java.util.Date (timeStamp * 1000L) funktioniert genauso gut (da 1000L ein langer Zeitstempel ist, wird er lange vor der Multiplikation
gesendet
2
Ich persönlich würde tun:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
Ryan Amaral
3
Zu Ihrer Information , die problematischen alten Datums- / Uhrzeitklassen, wie sie java.util.Datejetzt Legacy sind , werden durch die Klassen java.time ersetzt . Siehe Tutorial von Oracle .
Basil Bourque
59

java.time

Java 8 hat eine neue API für die Arbeit mit Datum und Uhrzeit eingeführt : das Paket java.time .

Mit java.time können Sie Ihre Anzahl ganzer Sekunden seit dem Epochenbezug des ersten Augenblicks von 1970 in UTC, 1970-01-01T00: 00Z, analysieren. Das Ergebnis ist ein Instant.

Instant instant = Instant.ofEpochSecond( timeStamp );

Wenn Sie einen benötigen java.util.Date, um mit altem Code zusammenzuarbeiten, der für java.time noch nicht aktualisiert wurde , konvertieren Sie. Rufen Sie neue Konvertierungsmethoden auf, die zu den alten Klassen hinzugefügt wurden.

Date date = Date.from( instant );
micha
quelle
3
Während diese Antwort technisch korrekt ist, beachten Sie, dass die Klassen java.time die problematischen alten Datums- / Uhrzeitklassen wie z java.util.Date. Die alten Klassen sind Vermächtnis und sollten vermieden werden. Während Sie tatsächlich in die Legacy- und java.time-Klassen konvertieren können, ist es am besten, wenn immer möglich bei java.time zu bleiben.
Basil Bourque
44

Das ist der richtige Weg:

Date date = new Date ();
date.setTime((long)unix_time*1000);
Marco Fantasia
quelle
27

Der Kalender scheint der neue Weg zu sein:

Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));

Die letzte Zeile ist nur ein Beispiel für die Verwendung. Diese würde zB "14.06.2012" drucken.

Wenn Sie System.currentTimeMillis () zum Speichern des Zeitstempels verwendet haben, benötigen Sie den Teil "* 1000" nicht.

Wenn Sie den Zeitstempel in einer Zeichenfolge haben, müssen Sie ihn zuerst als Long analysieren: Long.parseLong (Zeitstempel).

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

Stefan
quelle
8
Warnung: Wenn timestampes sich um eine Ganzzahl handelt, müssen Sie diese (long)zuerst umwandeln, da Sie sonst falsche Daten erhalten. mydate.setTimeInMillis((long) timestamp*1000);
Svenkapudija
Ich habe den Link behoben.
Ricbit
Zu Ihrer Information, die störenden alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque
26

tl; dr

Instant.ofEpochSecond( 1_280_512_800L )

2010-07-30T18: 00: 00Z

java.time

Das neue Java.time-Framework, das in Java 8 und höher integriert ist, ist der Nachfolger von Joda-Time.

Diese neuen Klassen enthalten eine praktische Factory-Methode zum Konvertieren einer Anzahl von ganzen Sekunden aus der Epoche. Sie erhalten Instanteinen Moment auf der Zeitachse in UTC mit einer Auflösung von bis zu Nanosekunden.

Instant instant = Instant.ofEpochSecond( 1_280_512_800L );

instant.toString (): 2010-07-30T18: 00: 00Z

Sehen Sie, wie der Code live auf IdeOne.com ausgeführt wird .

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

Asia/Kabuloder Asia/TehranZeitzonen?

Sie haben angegeben, dass Sie einen Tageszeitwert von 22:30 anstelle von 18:00 erhalten. Ich vermute, dass Ihr PHP-Dienstprogramm implizit eine Standardzeitzone zum Anpassen von UTC anwendet. Mein Wert hier ist UTC, bezeichnet durch Z(kurz für Zulubedeutet UTC). Gibt es eine Chance, dass Ihr Betriebssystem oder PHP auf Asia/Kabuloder Asia/TehranZeitzonen eingestellt ist? Ich nehme an, wie Sie IRSTin Ihrer Ausgabe berichten, was anscheinend Iran-Zeit bedeutet. Derzeit sind dies 2017 die einzigen Zonen mit einer Sommerzeit, die viereinhalb Stunden vor UTC liegt.

Geben Sie einen richtigen Zeitzonennamen im Format continent/region, wie zum Beispiel America/Montreal, Africa/Casablancaoder Pacific/Auckland. Verwenden Sie niemals die Abkürzung für 3-4 Buchstaben wie ESToder ISToder, IRSTda es sich nicht um echte Zeitzonen handelt, die nicht standardisiert und nicht einmal eindeutig (!) Sind.

Wenn Sie Ihren Moment durch die Linse der Zeitzone einer bestimmten Region sehen möchten , wenden Sie a ZoneIdan , um a zu erhalten ZonedDateTime. Immer noch der gleiche gleichzeitige Moment, aber als eine andere Wanduhrzeit gesehen .

ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z );  // Same moment, same point on timeline, but seen as different wall-clock time.

2010-07-30T22: 30 + 04: 30 [Asien / Teheran]

Konvertieren von java.time in Legacy-Klassen

Sie sollten bei den neuen java.time-Klassen bleiben. Bei Bedarf können Sie jedoch in alte konvertieren.

java.util.Date date = java.util.Date.from( instant );

Joda-Zeit

UPDATE: Das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Klassen java.time .

Zu Ihrer Information , der Konstruktor für eine Joda-Time DateTime ist ähnlich: Multiplizieren Sie mit Tausend, um eine long(keine int!) Zu erzeugen .

DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );

Vermeiden Sie am besten die notorisch lästigen Klassen java.util.Date und .Calendar. Wenn Sie jedoch ein Datum verwenden müssen, können Sie von Joda-Time konvertieren.

java.util.Date date = dateTime.toDate();

Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

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

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*Klassen.

Woher bekomme ich die java.time-Klassen?

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

Basil Bourque
quelle
11

Der Konstruktor von Date erwartet, dass der timeStamp-Wert in Millisekunden angegeben wird. Multiplizieren Sie den Wert Ihres Zeitstempels mit 1000 und übergeben Sie ihn an den Konstruktor.

f1sh
quelle
7

Wenn Sie einen Zeitstempelwert auf einem anderen Computer konvertieren, sollten Sie auch die Zeitzone dieses Computers überprüfen. Beispielsweise;

Die obigen Beschreibungen führen zu unterschiedlichen Datumswerten, wenn Sie mit EST- oder UTC-Zeitzonen arbeiten.

Zeitzone einstellen; aka zu UTC, können Sie einfach umschreiben;

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
tmr
quelle
6
Ich würde dies nicht empfehlen, da dies die Zeitzone für das gesamte JVM und nicht nur den Parsing-Prozess festlegt!
1

Für Kotlin

fun unixToDate(timeStamp: Long) : String? {
    val time = java.util.Date(timeStamp as Long * 1000)
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    return sdf.format(time)

}
Arda Kazancı
quelle
0

Manchmal müssen Sie mit Anpassungen arbeiten.

Verwenden Sie Cast nicht zu lange! Verwenden Sie die Nanoanpassung.

Wenn Sie beispielsweise die Oanda Java API für den Handel verwenden, können Sie datetime als UNIX-Format erhalten.

Zum Beispiel: 1592523410.590566943

    System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
    System.out.println("instant = " + Instant.ofEpochSecond(1592523410));

du erhältst:

instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z

Auch verwenden:

 Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
Damir Isanbirdin
quelle
-4
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
Masatsugu Hosoi
quelle
3
Ohne weiteren Text ist unklar, warum diese Antwort den vielen anderen in dieser Frage vorzuziehen ist. Können Sie bitte klarstellen?
Duncan Jones
Dadurch wird das Datum geändert, anstatt es zu konvertieren!
BackslashN