Java: Data od znacznika czasu unix

237

Muszę przekonwertować uniksowy znacznik czasu na obiekt daty.
Próbowałem tego:

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

Wartość znacznika czasu wynosi: 1280512800

Data powinna wynosić „2010/07/30 - 22:30:00” (tak jak otrzymuję to przez PHP), ale zamiast tego dostaję Thu Jan 15 23:11:56 IRST 1970.

Jak należy to zrobić?

RYN
źródło
3
Jeśli używasz Java 8 lub nowszej: spójrz na tę odpowiedź: stackoverflow.com/a/24703644/1115554
micha
1
Do Twojej wiadomości, kłopotliwe stare klasy daty i czasu, takie jak java.util.Dateteraz, są starsze , wyparte przez klasy java.time . Zobacz samouczek Oracle .
Basil Bourque

Odpowiedzi:

429

Dla 1280512800pomnożyć przez 1000, ponieważ java spodziewa milisekund:

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

Jeśli masz już milisekundy, to po prostu new java.util.Date((long)timeStamp);

Z dokumentacji :

Przydziela obiekt Date i inicjuje go, aby reprezentował określoną liczbę milisekund od standardowego czasu bazowego znanego jako „epoka”, a mianowicie 1 stycznia 1970 r., 00:00:00 GMT.

Pablo Santa Cruz
źródło
40
Rzutowanie na (long)jest bardzo ważne: bez niego liczba całkowita przepełnia się.
mneri
2
@TomasK java.util.Dateto w pełni kwalifikowana nazwa klasy. Datejest prawdopodobnie dokładnie tak samo, pod warunkiem, że zaimportujesz java.utilpakiet do swojej klasy.
Pablo Santa Cruz,
5
Obsada na długi nie jest potrzebna. time = new java.util.Date (timeStamp * 1000L) działa równie dobrze (ponieważ 1000L jest długim, znacznik czasu będzie upcastowany na długo przed pomnożeniem)
Tony BenBrahim 24'15
2
Osobiście zrobiłbym:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
Ryan Amaral
3
Do Twojej wiadomości, kłopotliwe stare klasy daty i czasu, takie jak java.util.Dateteraz, są starsze , wyparte przez klasy java.time . Zobacz samouczek Oracle .
Basil Bourque
59

java.time

Java 8 wprowadziła nowy interfejs API do pracy z datami i godzinami: pakiet java.time .

Dzięki java.time możesz przeanalizować liczbę sekund od odniesienia do pierwszej chwili 1970 roku w UTC, 1970-01-01T00: 00Z. Rezultatem jest Instant.

Instant instant = Instant.ofEpochSecond( timeStamp );

Jeśli potrzebujesz java.util.Datedo współpracy ze starym kodem, który nie został jeszcze zaktualizowany dla java.time , przekonwertuj. Wywołaj nowe metody konwersji dodane do starych klas.

Date date = Date.from( instant );
Micha
źródło
3
Chociaż technicznie ta odpowiedź jest poprawna, należy pamiętać, że klasy java.time zastępują kłopotliwe stare klasy daty i godziny, takie jak java.util.Date. Stare klasy są dziedzictwem i należy ich unikać. Chociaż rzeczywiście można konwertować do klas starszych i java.time, najlepiej trzymać java.time, gdy tylko jest to możliwe.
Basil Bourque,
44

To jest właściwy sposób:

Date date = new Date ();
date.setTime((long)unix_time*1000);
Marco Fantasia
źródło
27

Wygląda na to, że Kalendarz to nowy sposób:

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

Ostatni wiersz to tylko przykład, jak go użyć, ten wydrukuje np. „14.06.2012”.

Jeśli użyłeś System.currentTimeMillis () do zapisania znacznika czasu, nie potrzebujesz części „* 1000”.

Jeśli masz znacznik czasu w ciągu, musisz go najpierw przeanalizować jako długi: Long.parseLong (znacznik czasu).

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

Stefan
źródło
8
Ostrzeżenie: jeśli timestampjest liczbą całkowitą, musisz ją przerzucić na (long)pierwszą, w przeciwnym razie skończy się to z niewłaściwymi datami. mydate.setTimeInMillis((long) timestamp*1000);
svenkapudija
Naprawiłem link.
Ricbit
Do Twojej wiadomości, kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque,
26

tl; dr

Instant.ofEpochSecond( 1_280_512_800L )

2010-07-30T18: 00: 00Z

java.time

Nowa platforma java.time wbudowana w Javę 8 i późniejszą jest następcą Joda-Time.

Te nowe klasy obejmują przydatną fabryczną metodę konwersji liczby sekund z epoki. Dostajesz Instantchwilę na osi czasu w UTC z rozdzielczością do nanosekund.

Instant instant = Instant.ofEpochSecond( 1_280_512_800L );

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

Zobacz, jak kod działa na żywo w IdeOne.com .

Tabela typów daty i godziny w Javie, zarówno nowoczesnych, jak i starszych

Asia/Kabulczy Asia/Tehranstrefy czasowe?

Zgłosiłeś, że otrzymałeś wartość dnia 22:30 zamiast 18:00 tutaj. Podejrzewam, że twoje narzędzie PHP domyślnie stosuje domyślną strefę czasową do dostosowania z UTC. Moja wartość tutaj to UTC, oznaczony przez Z(skrót Zuluoznacza UTC). Jest jakaś szansa, urządzenie OS lub PHP jest ustawiony Asia/Kabullub Asia/Tehranstrefy czasowe? Podejrzewam, że tak, jak informujesz IRSTw swoich pracach, co najwyraźniej oznacza czas Iranu. Obecnie w 2017 r. Są to jedyne strefy działające w okresie letnim, który jest o cztery i pół godziny przed UTC.

Określ prawidłową nazwę strefy czasowej w formacie continent/region, takie jak America/Montreal, Africa/Casablancalub Pacific/Auckland. Nigdy nie używać skrótu 3-4 siÄ takich jak ESTlub ISTczy IRSTsą one nie prawdziwe strefy czasowe, niestandardowe, a nawet unikatowe (!).

Jeśli chcesz zobaczyć swoją chwilę przez soczewkę strefy czasowej określonego regionu, zastosuj a, ZoneIdaby uzyskać ZonedDateTime. Wciąż ten sam jednoczesny moment, ale postrzegany jako inny czas naścienny .

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 [Asia / Teheran]

Konwersja z java.time na starsze klasy

Powinieneś trzymać się nowych klas java.time. Ale w razie potrzeby możesz zmienić na stary.

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

Joda-Time

AKTUALIZACJA: Projekt Joda-Time jest teraz w trybie konserwacji , a zespół doradza migrację do klas java.time .

Do Twojej wiadomości, konstruktor JTA-Time DateTime jest podobny: pomnóż przez tysiąc, aby utworzyć long(nie an int!).

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

Najlepiej, aby uniknąć kłopotliwych klas java.util.Date i .Calendar. Ale jeśli musisz użyć Daty, możesz dokonać konwersji z Joda-Time.

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

O java.time

Środowisko java.time jest wbudowane w Javę 8 i nowsze wersje . Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date, Calendar, i SimpleDateFormat.

Projekt Joda-Time , teraz w trybie konserwacji , zaleca migrację do klas java.time .

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie potrzeba ciągów, nie ma potrzeby java.sql.*klas.

Gdzie można uzyskać klasy java.time?

Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .

Basil Bourque
źródło
11

Konstruktor daty oczekuje, że wartość timeStamp będzie wyrażona w milisekundach. Pomnóż wartość znacznika czasu przez 1000, a następnie przekaż konstruktorowi.

f1sh
źródło
7

Jeśli konwertujesz wartość znacznika czasu na innym komputerze, powinieneś również sprawdzić strefę czasową tego komputera. Na przykład;

Powyższe odszyfrowania przyniosą różne wartości Daty, jeśli uruchomisz w strefach czasowych EST lub UTC.

Aby ustawić strefę czasową; znany też jako UTC, możesz po prostu przepisać;

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
tmr
źródło
6
Nie polecałbym tego, ponieważ ustawia to strefę czasową dla całego środowiska JVM, a nie tylko procesu analizowania!
1

Dla kotlina

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ı
źródło
0

Czasami musisz pracować z dostosowaniami.

Nie używaj obsady zbyt długo! Użyj nanoregulacji.

Na przykład, używając Oanda Java API do handlu, możesz uzyskać datetime w formacie UNIX.

Na przykład: 1592523410.590566943

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

dostajesz:

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

Użyj również:

 Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
Damir Isanbirdin
źródło
-4
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
Masatsugu Hosoi
źródło
3
Bez dodatkowego tekstu nie jest jasne, dlaczego ta odpowiedź jest lepsza od wielu innych w tym pytaniu. Czy możesz wyjaśnić?
Duncan Jones
Spowoduje to zmianę daty zamiast jej konwersji!
backslashN