Uzyskiwanie „unixtime” w Javie

258

Date.getTime () zwraca milisekundy od 1 stycznia 1970 roku. Unixtime to sekundy od 1 stycznia 1970 roku. Zwykle nie koduję w Javie, ale pracuję nad poprawkami błędów. Mam:

Date now = new Date();      
Long longTime = new Long(now.getTime()/1000);
return longTime.intValue();

Czy istnieje lepszy sposób na uzyskanie czasu uniksowego w Javie?

Gary Richardson
źródło
27
Ponieważ rzuciłeś go na int, wprowadziłeś problem roku 2038 (odpowiednik Y2K dla Uniksa). Wtedy epoka uniksowa osiąga 2 miliardy i przechodzi do wartości ujemnej. Rozwiązaniem jest przejście na 64-bitowy system Unix. Odpowiednikiem Java jest pozostawienie go jako długiego.
John M
1
Tak, jestem tego świadomy. Kod, z którym jest połączony, oczekuje 32-bitowej int dla unixtime.
Gary Richardson
157
2038 już wkrótce.
Pacerier
Czy istnieje poprawna nazwa lub standard dla currentTimeMillis? W mojej dokumentacji nazywam to milisekundową wersją czasu UNIX.
Tom
1
Jeśli chcesz, aby twoje oprogramowanie przetrwało przepełnienie, użyj long, nie int. Naprawdę nie ma powodu, aby używać intznacznika czasu, chyba że używasz innej ziarnistości, takiej jak 1 sekunda = 4 sekundy itp. Albo to, albo ukryj swój kod, aby przyszłe generacje nie mogły zobaczyć, jak jesteś niekompetentny.
bryc

Odpowiedzi:

475

Unikaj tworzenia obiektów Date w / System.currentTimeMillis () . Dzielenie przez 1000 prowadzi do epoki uniksowej.

Jak wspomniano w komentarzu, zwykle chcesz, aby pierwotny długi (o małej l-długości) nie był długim obiektem w ramce (o dużej długości L) dla typu zmiennej unixTime.

long unixTime = System.currentTimeMillis() / 1000L;
John M.
źródło
3
Rozważ też użycie prymitywnej długiej zamiast autoboksowania do Długiej, chyba że chcesz obsłużyć liczbę jako Obiekt (np. Umieścić ją w Kolekcji), ponownie unika się niepotrzebnego tworzenia obiektów
brabster
9
32-bitowa wersja Java pasuje do platform 32-bitowych (i problem z rokiem 2038). Platformy 64-bitowe używają większego typu danych time_t. Java uniknął tego pocisku, używając znaku powrotu jako System.currentTimeMillis (). W przypadku konwersji na int ponownie wprowadzasz problem z 2038 r. Zobacz en.wikipedia.org/wiki/Rok_2038_problem#Solutions
John M
1
Myślę, że mylisz się co do jednego punktu: nie ma różnicy między małą literą „L” a wielką literą, gdy używasz ich w literałach numerycznych takich jak ten. docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1
Matt Forsythe
5
Dyskusja o wielkich literach (wyjaśniona powyżej) dotyczyła typu danych. Pierwotna instancja klasy „long” vs ”java.lang.Long”. Mówisz o sufiksie na długim literale, który, jak się zgadzam, może być wielką lub małą literą. Chociaż małe litery „l” wyglądają jak cyfra „1”, więc o wiele bardziej czytelne jest użycie dużej litery „L”.
John M
1
Kliknij link do dokumentacji. Zwrot jest definiowany jako liczba milisekund od 1/1/1970 w strefie czasowej UTC. Chcesz strefy czasowe? Spójrz na java.util.Calendar.
John M,
273

Java 8 dodała nowy interfejs API do pracy z datami i godzinami. Z Javą 8 możesz korzystać

import java.time.Instant
...
long unixTimestamp = Instant.now().getEpochSecond();

Instant.now()zwraca Instant, który reprezentuje bieżący czas systemowy. Z getEpochSecond()dostaniesz sekund epoki (czas uniksowy) od Instant.

Micha
źródło
4
Jaka jest różnica między Instant.now().getEpochSecond(),new Date().getTime() aSystem.currentTimeMillis()
SohamC
2
Jedną różnicą jest to, że pierwsza jest w sekundach, a druga w milisekundach. Mogą istnieć inne osoby.
super_aardvark 27.04.16
3
import java.time.Instant jeśli jesteś w Scali
akauppi
4
Sprawdź również tę stronę, aby uzyskać szczegółowy opis ... Podobało mi się .. currentTimeMillis
Subroto
1
Pamiętaj, że nie możesz używać tej metody ze starszymi poziomami API Androida.
Ali Nadalizadeh