System.currentTimeMillis()返回UTC时间?


93

我想以毫秒为单位获取当前UTC时间。我搜索了google,并得到了一些System.currentTimeMillis()返回UTC时间的答案。但事实并非如此。如果我执行以下操作:

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

这三个时间几乎都相同(由于通话,相差以毫秒为单位)。

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

这不是UTC时间,而是我的时区时间。如何在Android中获取当前UTC时间?


4
返回自1970年1月1日UTC
Blackbelt


3
长t3 = Calendar.getInstance(TimeZone.getTimeZone(“ UTC”))。getTimeInMillis();
Blackbelt

3
上面的链接说:“有关“计算机时间”与协调世界时(UTC)之间可能出现的细微差异的讨论,请参见“日期”类的描述。” 并在java.util.Date文档中找到:“尽管Date类旨在反映协调世界时(UTC),但它可能不能完全反映协调的通用时间(UTC),具体取决于Java虚拟机的宿主环境”->因此您的计算机返回非UTC时间的可能性
Marco Forberg 2013年

4
@ g.revolution:这是“自1970年1月1日UTC以来的毫秒数”-您希望如何调整时区?您所在的时区不影响自该时期以来已发生的毫秒数。
乔恩·斯基特

Answers:


132

您显示的所有三行都将给出自unix纪元以来的毫秒数,这是一个固定的时间点,不受本地时区的影响。

您说“现在不是UTC时间”-我怀疑您实际上是错误地诊断了这一点。我建议为此使用epochconverter.com。例如,在您的示例中:

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

我们不知道您何时生成该值,但是除非它实际上是UTC上午8:01 ,否则这是系统时钟的问题。

无论是System.currentTimeMillis也不是中值Date本身是由时区的影响。但是,您应该知道,Date.toString() 它确实使用了本地时区,这使许多开发人员误认为a Date与时区固有地相关-并非如此,它只是即时的,没有相关的时区甚至日历系统。


6
因此,基本上,就是说,如果在不同时区内同时调用此函数,则该函数返回相同的值,而与主机的时钟无关,对吗?
菲利普(Phillip)

14
老兄,这让我希望世界能够(可以)采用一个时区。谁在乎时钟数字是00:00还是08:00当天空中出现大的明亮物体时?数不清的原本浪费在这个历史遗迹上的生产时间浪费了我的血液……
corsiKa 2015年

与此相关,请注意,对操作系统时钟功能的基础调用具有记录的几毫秒的“漂移”。如果要获得高精度的操作持续时间(任务开始和结束的时间,时间增量是经过的时间),则Java具有“高性能计时器”。请参阅:docs.oracle.com/javase/7/docs/api/java/lang/...
达雷尔-蒂格

@JonSkeet如果toString()在内部使用时区,如何在没有时区的情况下从中构建字符串。实际上,我正在REST服务器中生成文件,该文件的文件名确切为午夜时间值ex“ 1551139200.json”(2019年2月26日,12:00:00 AM),并且一旦设备的System.currentTimeMillis()就需要从android应用程序进行访问返回确切时间。
kiranking

@kiranking:Date.getTime()用于查找自Unix时代以来的毫秒数,除以1000(因为该文件名距离Unix时代以来的秒数),然后将该整数格式化为字符串。
乔恩·斯基特

3

我可以确认,考虑到时期,这三个调用都可能取决于本地时间,而不是Date.toString()或类似方法。我已经看到它们取决于运行Android 2.3的特定设备中的本地时间。我尚未在其他设备和android版本上测试过它们。在这种情况下,本地时间是手动设置的。

获得独立UTC时间的唯一可靠方法是使用来请求位置更新GPS_PROVIDERgetTime()从中检索到的位置的值NETWORK_PROVIDER还取决于本地时间。例如,另一种选择是ping返回UTC时间戳的服务器。

因此,我要做的是:

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环境的时区值没有任何关系。
Darrell Teague

@DarrellTeague我坚持认为,我在特定的华为设备中看到了不同的值。因此,不,它并不总是返回正确的UTC时间(舍弃精度差异)
jlhonora 2016年

OP的问题是关于Java类时区的用法。这与硬件或返回的时间值的准确性无关。简而言之,JVM从(抽象的)操作系统“系统时钟”获取时间(该时间因操作系统的功能而异)。另请参见:drdobbs.com/embedded-systems/…和操作系统上的“ C”实现chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Darrell Teague
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.