Mendapatkan "unixtime" di Java

258

Date.getTime () mengembalikan milidetik sejak 1 Januari 1970. Unixtime adalah detik sejak 1 Januari 1970. Saya biasanya tidak kode di java, tapi saya sedang mengerjakan beberapa perbaikan bug. Saya sudah:

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

Apakah ada cara yang lebih baik untuk mendapatkan unixtime di java?

Gary Richardson
sumber
27
Karena Anda memasukkannya ke int, Anda telah memperkenalkan masalah tahun 2038 (setara dengan Y2K untuk Unix). Saat itulah zaman Unix mencapai 2 miliar dan berguling ke negatif. Cara mengatasinya adalah pindah ke Unix 64-bit. Setara dengan Java adalah membiarkannya sebagai panjang.
John M
1
Ya, saya tahu itu. Kode yang berinteraksi dengan ini mengharapkan int 32bit untuk unixtime.
Gary Richardson
158
2038 akan segera hadir.
Pacerier
Apakah ada nama atau standar yang tepat untuk currentTimeMillis? Saya cenderung menyebutnya dalam dokumentasi saya sebagai versi milidetik dari waktu UNIX.
Tom
1
Jika Anda ingin perangkat lunak Anda selamat dari overflow, gunakan long, jangan int. Tidak ada alasan untuk menggunakan intcap waktu, kecuali jika Anda menggunakan rincian yang berbeda seperti 1 detik = 4 detik dll. Entah itu, atau sembunyikan kode Anda sehingga generasi mendatang tidak dapat melihat betapa tidak kompetennya Anda.
bryc

Jawaban:

475

Hindari pembuatan objek Date w / System.currentTimeMillis () . Membagi dengan 1000 membawa Anda ke zaman Unix.

Seperti disebutkan dalam komentar, Anda biasanya menginginkan panjang primitif (huruf kecil-l panjang) bukan objek kotak panjang (kapital-L Panjang) untuk tipe variabel unixTime.

long unixTime = System.currentTimeMillis() / 1000L;
John M
sumber
3
Juga mempertimbangkan menggunakan primitif panjang, bukan autoboxing ke Long, kecuali jika Anda ingin menangani jumlah sebagai Obyek (seperti memasukkannya ke dalam Collection), lagi menghindari pembuatan obyek yang tidak perlu
brabster
9
Java 32-bit int cocok dengan platform 32-bit (dan masalah tahun 2038). Platform 64-bit menggunakan tipe data time_t yang lebih besar. Java menghindari peluru itu dengan menggunakan selama pengembalian untuk System.currentTimeMillis (). Jika Anda mengonversi ke int, Anda akan memperkenalkan kembali masalah tahun 2038. Lihat en.wikipedia.org/wiki/Year_2038_problem#Solutions
John M
1
Saya pikir Anda salah pada satu titik: Tidak ada perbedaan antara huruf kecil "L" dan huruf besar ketika menggunakannya dalam literal numerik seperti ini. docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1
matt forsythe
5
Diskusi kapitalisasi (dijelaskan di atas) adalah tentang tipe data. Contoh kelas primitif "long" vs "java.lang.Long". Anda sedang berbicara tentang huruf akhiran pada literal panjang, yang saya setuju bisa huruf besar atau kecil. Meskipun huruf kecil "l" terlihat sangat mirip digit "1" sehingga jauh lebih mudah untuk menggunakan huruf kapital "L".
John M
1
Klik tautan ke dokumentasi. Pengembalian didefinisikan sebagai jumlah milidetik sejak 1/1/1970 di zona waktu UTC. Anda ingin zona waktu? Lihatlah java.util.Calendar.
John M
273

Java 8 menambahkan API baru untuk bekerja dengan tanggal dan waktu. Dengan Java 8 Anda bisa menggunakan

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

Instant.now()mengembalikan Instan yang mewakili waktu sistem saat ini. Dengan getEpochSecond()Anda mendapatkan waktu detik (waktu unix) dari Instant.

micha
sumber
4
Apa perbedaan antara Instant.now().getEpochSecond(), new Date().getTime()danSystem.currentTimeMillis()
SohamC
2
Satu perbedaan adalah bahwa yang pertama dalam detik sedangkan dua yang kedua dalam milidetik. Mungkin ada atau tidak ada orang lain.
super_aardvark
3
import java.time.Instantjika Anda berada di Scala
akauppi
4
Periksa situs ini juga untuk penjelasan terperinci ... Menyukainya .. currentTimeMillis
Subroto
1
Perhatikan bahwa Anda tidak dapat menggunakan metode ini dengan Level API Android yang lebih lama.
Ali Nadalizadeh