apakah System.currentTimeMillis () mengembalikan waktu UTC?

93

Saya ingin mengetahui waktu UTC saat ini dalam milidetik. Saya mencari di google dan mendapatkan beberapa jawaban bahwa System.currentTimeMillis () mengembalikan waktu UTC. tapi ternyata tidak. Jika saya melakukan berikut ini:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

ketiganya hampir sama (perbedaannya dalam mili detik karena panggilan).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

dan kali ini bukan waktu UTC melainkan waktu zona waktu saya. Bagaimana saya bisa mendapatkan waktu UTC saat ini di Android?

g. revolusi
sumber
5
Mengembalikan waktu sistem saat ini dalam milidetik sejak 1 Januari 1970 00:00:00 UTC
Blackbelt
3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt
3
Tautan di atas mengatakan "Lihat deskripsi Tanggal kelas untuk diskusi tentang sedikit perbedaan yang mungkin timbul antara" waktu komputer "dan waktu universal terkoordinasi (UTC)." dan dalam dokumentasi java.util.Date Anda akan menemukan: "Meskipun kelas Tanggal dimaksudkan untuk mencerminkan waktu universal terkoordinasi (UTC), itu mungkin tidak melakukannya dengan tepat, tergantung pada lingkungan host dari Mesin Virtual Java" -> jadi mungkin ada kemungkinan bahwa mesin Anda mengembalikan waktu non-UTC
Marco Forberg
4
@ g.revolution: Ini adalah "jumlah milidetik sejak 1 Januari 1970 00:00:00 UTC" - bagaimana Anda mengharapkan penyesuaian untuk zona waktu? Zona waktu lokal Anda tidak memengaruhi berapa milidetik yang telah terjadi sejak periode tersebut.
Jon Skeet

Jawaban:

134

Ketiga baris yang Anda tunjukkan akan memberikan jumlah milidetik sejak periode unix, yang merupakan titik waktu tetap, tidak terpengaruh oleh zona waktu lokal Anda.

Anda mengatakan "kali ini bukan waktu UTC" - Saya curiga Anda sebenarnya telah salah mendiagnosisnya. Saya akan menyarankan menggunakan epochconverter.com untuk ini. Misalnya, dalam contoh Anda:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

Kami tidak tahu kapan Anda menghasilkan nilai itu, kecuali jika itu sebenarnya pada 8:01 UTC, itu masalah dengan jam sistem Anda.

Baik System.currentTimeMillisnilai di dalam Datedirinya sendiri tidak terpengaruh oleh zona waktu. Namun, Anda harus menyadari bahwa Date.toString() itu menggunakan zona waktu lokal, yang menyesatkan banyak pengembang untuk berpikir bahwa a Dateterkait erat dengan zona waktu - ini bukan, ini hanya sekejap dalam waktu, tanpa zona waktu terkait atau bahkan sistem kalender.

Jon Skeet
sumber
6
Jadi pada dasarnya, artinya fungsi ini mengembalikan nilai yang sama jika dipanggil pada waktu yang sama dari dalam zona waktu yang berbeda, terlepas dari jam host, benar?
Phillip
15
Man ini membuatku berharap dunia akan (bisa) mengadopsi satu zona waktu. Siapa yang peduli jika angka pada jam adalah 00:00 atau 08:00 ketika benda terang besar muncul di langit? Berjam-jam waktu produktif yang terbuang percuma untuk peninggalan sejarah ini membuat darah saya mendidih ...
corsiKa
Terkait dengan ini, perhatikan bahwa panggilan yang mendasari ke fungsi jam OS memiliki 'penyimpangan' yang didokumentasikan selama beberapa milidetik. Java memiliki 'pengatur waktu kinerja tinggi' jika tujuannya adalah untuk mendapatkan durasi operasi yang sangat presisi (pengaturan waktu saat tugas dimulai dan selesai, delta adalah jumlah waktu yang telah berlalu). Lihat: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague
@ JonSkeet jika toString () secara internal menggunakan zona waktu bagaimana saya bisa membangun string darinya tanpa zona waktu. Sebenarnya saya membuat file di server REST yang memiliki nama file persis dengan nilai waktu tengah malam ex "1551139200.json" (26 Februari 2019 12:00:00) dan itu perlu diakses dari aplikasi android setelah System.currentTimeMillis () perangkat mengembalikan waktu yang tepat.
Kiranking
@kiranking: Gunakan Date.getTime()untuk menemukan waktu milidetik-sejak-Unix-epoch, bagi dengan 1000 (karena nama file itu dalam detik sejak zaman Unix) dan cukup format integer itu sebagai string.
Jon Skeet
2

Saya dapat mengonfirmasi bahwa ketiga panggilan dapat bergantung pada waktu setempat, dengan mempertimbangkan zaman, bukanDate.toString() atau yang serupa. Saya telah melihatnya bergantung pada waktu lokal di perangkat tertentu yang menjalankan Android 2.3. Saya belum mengujinya dengan perangkat lain dan versi Android. Dalam kasus ini, waktu lokal telah diatur secara manual.

Satu-satunya cara yang dapat diandalkan untuk mendapatkan waktu UTC independen adalah meminta pembaruan lokasi menggunakan GPS_PROVIDER. The getTime()nilai lokasi diambil dariNETWORK_PROVIDER juga tergantung pada waktu setempat. Opsi lainnya adalah melakukan ping ke server yang mengembalikan stempel waktu UTC, misalnya.

Jadi, yang saya lakukan adalah sebagai berikut:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}
jlhonora.dll
sumber
1
System.currentTimeMillis () mengembalikan nilai berbasis UTC. Adapun 'ketepatan' atau akurasi jam sistem operasi yang bersangkutan, sementara tentu saja ini mempengaruhi hasil, sama sekali tidak terkait dengan sistem atau nilai zona waktu lingkungan Java.
Darrell Teague
@DarrellTeague Saya bersikeras, saya melihat nilai yang berbeda di perangkat Huawei tertentu. Jadi tidak, itu tidak selalu mengembalikan waktu UTC yang benar (membuang perbedaan akurasi)
jlhonora
Pertanyaan OP adalah tentang penggunaan zona waktu kelas Java. Ini bukan tentang perangkat keras atau keakuratan nilai waktu yang dikembalikan. Sederhananya, JVM mendapatkan waktunya dari "jam sistem" operasi (abstrak) (yang bervariasi berdasarkan sistem operasi dalam hal bagaimana fungsinya). Lihat juga: drdobbs.com/embedded-systems/… dan implementasi "C" pada sistem operasi chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague