System.currentTimeMillis()はUTC時間を返しますか?


93

現在のUTC時間をミリ秒で取得したい。私はグーグルを検索し、System.currentTimeMillis()がUTC時間を返すといういくつかの回答を得ました。しかし、そうではありません。私が次のことをした場合:

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

3つの時間はすべてほぼ同じです(違いは呼び出しによるミリ秒単位です)。

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

この時間はUTC時間ではなく、私のタイムゾーン時間です。Androidで現在のUTC時間を取得するにはどうすればよいですか?


4
1970年1月1日00:00:00 UTCから現在のシステム時刻をミリ秒単位で返します
Blackbelt 2013年


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

3
上記のリンクは、「 "コンピューターの時刻"と協定世界時(UTC)の間に生じる可能性のあるわずかな不一致については、日付クラスの説明を参照してください。」また、java.util.Dateのドキュメントでは、「Dateクラスは協定世界時(UTC)を反映することを目的としていますが、Java仮想マシンのホスト環境によっては正確に反映されない場合があります」->マシンが非UTC時間を返す可能性
Marco Forberg

4
@ g.revolution:「1970年1月1日からのミリ秒数00:00:00 UTC」-タイムゾーンに合わせて調整するにはどうすればよいですか。ローカルタイムゾーンは、そのエポック以降に発生したミリ秒数には影響しません。
Jon Skeet 2013年

回答:


132

これまでに示した3本の線はすべて、UNIXエポックからのミリ秒数を示します。これは、ローカルタイムゾーンの影響を受けない、固定された時点です。

「今回はUTC時間ではありません」-あなたは実際にそれを誤って診断したのではないかと思います。これにはepochconverter.comを使用することを勧めします。たとえば、あなたの例では:

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

その値がいつ生成されたかはわかりませんが、実際にはUTC午前8:01でない限り、システムクロックに問題があります。

タイムゾーンの影響も受けませSystem.currentTimeMillisDate。しかし、あなたがそれを認識する必要がありますDate.toString() ないという考えに誤解させる多くの開発者をローカルタイムゾーン、使用Date本質的にタイムゾーンに関連付けられている-それはないですが、それは、関連するタイムゾーン、あるいはカレンダーシステムのない時間でちょうど瞬間、です。


6
つまり、基本的には、この関数は、ホストのクロックに関係なく、異なるタイムゾーン内から同時に呼び出された場合に同じ値を返すということです。
フィリップ

14
これは、世界が単一のタイムゾーンを採用することを望んでいることになります。大きな明るいものが空に現れたときに、時計の数字が00:00か08:00かどうかは誰が気にしますか?この歴史的な遺物で無駄な時間を費やして無数の時間を費やしていると、私の血が沸騰します...
corsiKa

これに関連して、OSクロック関数の基本的な呼び出しには、数ミリ秒の「ドリフト」が記録されていることに注意してください。Javaには、操作の非常に正確な継続時間(タスクの開始と終了のタイミング、デルタは経過時間)を取得することが目的である場合、「高性能タイマー」があります。参照:docs.oracle.com/javase/7/docs/api/java/lang/...
ダレル・ティーグ

@JonSkeetもしtoString()が内部的にタイムゾーンを使用する場合、タイムゾーンなしでそこから文字列を構築するにはどうすればよいでしょうか。実際には、「1551139200.json」の真夜中の時刻の値と正確に一致するファイル名を持つファイルをRESTサーバーで生成しています(2019年2月26日12:00:00 AM)。デバイスのSystem.currentTimeMillis()の後にAndroidアプリからアクセスする必要があります正確な時刻を返します。
ランキング

@kiranking:Date.getTime()ミリ秒以降のUnixエポック時間を検索し、1000で除算し(そのファイル名はUnixエポックからの秒数であるため)、その整数を文字列としてフォーマットするだけです。
ジョンスキート、

3

3つすべての呼び出し、エポックを考慮して、現地時間に依存する可能性があることを確認できますDate.toString()。私は、Android 2.3を実行している特定のデバイスのローカル時間に依存することを確認しました。他のデバイスやAndroidバージョンではテストしていません。この場合、現地時間は手動で設定されました。

独立したUTC時間を取得する唯一の信頼できる方法は、を使用して位置情報の更新をリクエストすることGPS_PROVIDERです。getTime()から取得した場所の値は、NETWORK_PROVIDER現地時間にも依存します。別のオプションは、たとえば、UTCタイムスタンプを返すサーバーにpingすることです。

だから、私がすることは次のとおりです:

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ベースの値を返します。オペレーティングシステムクロックの「精度」または精度に関しては、確かに結果に影響しますが、システムまたはJava環境のタイムゾーン値とは関係ありません。
ダレルティーグ

@DarrellTeague私は主張します、私は特定のHuaweiデバイスで異なる値を見ました。したがって、いいえ、それは常に正しいUTC時間を返すとは限りません(精度の違いを破棄します)
jlhonora

OPの質問は、Javaクラスのタイムゾーンの使用についてでした。これは、ハードウェアや返された時間値の正確さに関するものではありませんでした。簡単に言うと、JVMは(抽象的な)動作している「システムクロック」から時間を取得します(システムクロックは、オペレーティングシステムによって機能が異なります)。参照:drdobbs.com/embedded-systems/…およびオペレーティングシステムでの "C"実装chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.