System.currentTimeMillis () UTC saatini döndürür mü?


94

Geçerli UTC saatini milis cinsinden almak istiyorum. Google'da arama yaptım ve System.currentTimeMillis () 'in UTC saatini döndürdüğü yanıtları aldım. ama öyle değil. Aşağıdakileri yaparsam:

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

üç sefer de hemen hemen aynıdır (aramalardan kaynaklanan fark mili saniye cinsindendir).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

ve bu saat UTC saati değil, bunun yerine benim zaman dilimim. Android'de geçerli UTC saatini nasıl alabilirim?


5
1 Ocak 1970 00:00:00 UTC
Blackbelt


3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt

3
Yukarıdaki bağlantı, "Bilgisayar saati" ve eşgüdümlü evrensel saat (UTC) arasında ortaya çıkabilecek küçük farklılıklar hakkında bir tartışma için sınıf Tarihinin açıklamasına bakın "diyor. ve java.util.Date belgelerinde şunu bulursunuz: "Date sınıfının koordineli evrensel saati (UTC) yansıtması amaçlansa da, Java Sanal Makinesi'nin ana bilgisayar ortamına bağlı olarak bunu tam olarak yapmayabilir" -> bu nedenle makinenizin UTC olmayan bir saatte
dönmesi

4
@ g.revolution: "1 Ocak 1970 00:00:00 UTC'den bu yana geçen milisaniye sayısı" - bunun bir saat dilimi için nasıl ayarlanmasını beklersiniz? Yerel saat diliminiz, o dönemden bu yana kaç milisaniyenin gerçekleştiğini etkilemez.
Jon Skeet

Yanıtlar:


136

Gösterdiğiniz üç satırın tümü, yerel saat diliminizden etkilenmeyen, zamanda sabit bir nokta olan unix döneminden bu yana geçen milisaniye sayısını verecektir.

"Bu saat UTC saati değil" diyorsunuz - Aslında bunu yanlış teşhis ettiğinizden şüpheleniyorum. Bunun için epochconverter.com'u kullanmanızı öneririm . Örneğin, sizin örneğinizde:

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

Bu değeri ne zaman oluşturduğunuzu bilmiyoruz, ancak gerçekte 08:01 UTC olmadıkça , bu sistem saatinizle ilgili bir sorundur.

Ne System.currentTimeMillisne de Datekendi içindeki değer saat diliminden etkilenmez. Bununla birlikte, yerel saat dilimini kullandığının farkında olmalısınız ki Date.toString() bu , birçok geliştiriciyi, a'nın Datedoğası gereği bir saat dilimi ile ilişkili olduğunu düşünmeye yönlendirir - bu, ilişkili bir saat dilimi ve hatta takvim sistemi olmadan, yalnızca bir anlık zamandır.


6
Yani temelde, bu işlev, ana bilgisayarın saatine bakılmaksızın, farklı zaman dilimlerinde aynı anda çağrıldığında aynı değeri döndürdüğünü söylemek, doğru mu?
Phillip

16
Adamım bu, dünyanın tek bir zaman dilimini benimsemesini dilememi sağlıyor. Gökyüzünde büyük parlak şey göründüğünde saatin üzerindeki sayı 00:00 veya 08:00 kimin umurunda? Bu tarihi kalıntı üzerinde boşa harcanan sayısız saatlerce üretken zaman
kanımın

Bununla ilgili olarak, işletim sistemi saat işlevine yapılan temel çağrının, birkaç milisaniyelik belgelenmiş bir 'kayması' olduğunu unutmayın. Java, bir işlemin oldukça hassas bir süresini elde etmekse (bir görevin başlayıp bittiği zamanlama, delta geçen süre) 'yüksek performanslı bir zamanlayıcıya' sahiptir. Bakınız: docs.oracle.com/javase/7/docs/api/java/lang/…
Darrell Teague

@JonSkeet eğer toString () dahili olarak saat dilimini kullanıyorsa, saat dilimi olmadan ondan nasıl dize oluşturabilirim. Aslında REST sunucusunda dosya adı tam olarak "1551139200.json" (26 Şubat 2019 12:00:00 AM) eski gece yarısı değerine sahip olan ve cihazın System.currentTimeMillis () bir kez android uygulamasından erişilmesi gereken dosya oluşturuyorum. tam zamanı döndürür.
kiranking

@kiranking: Date.getTime()Unix döneminden beri geçen milisaniyeleri bulmak için kullanın , 1000'e bölün (bu dosya adı Unix döneminden bu yana saniye cinsinden olduğu için) ve bu tamsayıyı bir dize olarak biçimlendirin.
Jon Skeet

2

Ben her üç çağrıları teyit edebiliriz olabilir dönemini değil, düşünen, yerel saatle bağlı Date.toString()veya herhangi benzer bir yöntem. Bunların Android 2.3 çalıştıran belirli cihazlarda yerel saate bağlı olduğunu gördüm. Bunları diğer cihazlar ve android sürümleriyle test etmedim. Bu durumda yerel saat manuel olarak ayarlanmıştır.

Bağımsız bir UTC saati almanın tek güvenilir yolu GPS_PROVIDER,. Alınan getTime()bir konumun değeri NETWORK_PROVIDERde yerel saate bağlıdır. Diğer bir seçenek, örneğin, UTC zaman damgası döndüren bir sunucuya ping atmaktır.

Yani, yaptığım şey şu:

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;
}

1
System.currentTimeMillis (), UTC tabanlı bir değer döndürür. İşletim sistemi saatinin 'kesinliği' veya doğruluğu söz konusu olduğunda, bu kesinlikle sonucu etkilerken, hiçbir şekilde sistem veya Java ortamı saat dilimi değeriyle ilgili değildir.
Darrell Teague

@DarrellTeague Israr ediyorum, belirli bir Huawei cihazında farklı değerler gördüm. Yani hayır, her zaman doğru UTC saatini döndürmez (doğruluk farklarını
göz ardı ederek

OP'nin sorusu Java sınıfı saat dilimi kullanımıyla ilgiliydi. Bu, donanım veya döndürülen zaman değerinin doğruluğu ile ilgili değildi. Basitçe ifade etmek gerekirse, JVM zamanını (soyut) işletim "sistem saatinden" alır (nasıl çalıştığı açısından işletim sistemine göre değişir). Ayrıca bkz: drdobbs.com/embedded-systems/… ve işletim sistemlerindeki "C" uygulamaları chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.