首页 > 解决方案 > 当用户手动更改时间时 System.currentTimeMillis() 会受到干扰

问题描述

我正在构建对时间敏感的应用程序,即某些任务需要在一定时间内完成。有多种获取时间的方法,System.currentTimeMillis()gpsLocation.getTime(). 我不想使用System.currentTimeMillis(),因为用户可以手动更改时间。怎么样gpsLocation.getTime()?我观察到在某些地区,设备无法获取GPS位置。那timestamp我应该用哪个?

位置时间戳

open fun onLocationChanged(location: Location?) {
    ellapsedTime = location.getTime()
}

我正在检测用户是否使用以下代码更改了自动时间和时区设置:

val isAutoTime = Settings.Global.getInt(activity!!.getContentResolver(), Settings.Global.AUTO_TIME)
        val isAutoTimezone = Settings.Global.getInt(activity!!.getContentResolver(), Settings.Global.AUTO_TIME_ZONE)

我应该使用什么方法来获取时间戳?

问题中缺少什么?

请评论缺少的部分是什么?或者您可能不理解问题/疑虑。我正在写比较时间戳的最佳方法。System.currentTimeinMillis()我添加了使用and的优缺点location.getTime()。由于应用程序是时间相关的,所以如果用户使用时间设置,那么我应该能够比较准确的时间戳而不是系统时间。

标签: androidandroid-locationandroid-gpsandroid-date

解决方案


从您告诉我们的情况来看,这似乎System.nanoTime()是一个不错的选择。相反System.currentTimeMillis()不受用户手动设置设备系统时钟的影响System.nanoTime()。因此,即使他们这样做了,在您的程序中,您也可以可靠地计算基于.System.nanoTime()

System.nanoTme()承诺只要 JVM 正在运行,就会可靠地测量经过的时间。因此,只要您的程序正在运行,您就有可靠的测量结果。他们说该方法确实为您提供了自设备启动以来的纳秒数,如果是这样,只要设备未重新启动,您还可以跨程序运行进行测量。但不能保证后者,并且可能与下一个 Android 版本不同。

有关差异的演示,请参见以下代码段:

    long millis0 = System.currentTimeMillis();
    long nanos0 = System.nanoTime();

    System.out.println("Type a line to continue");
    new Scanner(System.in).nextLine();

    long millis1 = System.currentTimeMillis();
    long nanos1 = System.nanoTime();

    System.out.println("Elapsed time according to System.currentTimeMillis(): " + Duration.ofMillis(millis1 - millis0));
    System.out.println("Elapsed time according to System.nanoTime(): " + Duration.ofNanos(nanos1 - nanos0));

我在我的电脑上运行它,并在中间将电脑时钟调整了一个小时。会议看起来像:

Type a line to continue
I have now adjusted the computer clock
Elapsed time according to System.currentTimeMillis(): PT1H16.169S
Elapsed time according to System.nanoTime(): PT28.359865564S

所以从System.currentTimeMillis()它错误地看起来已经过了 1 小时 16.169 秒。System.nanoTime()说实话:只过去了 28.359865564 秒。

链接: 文档System.nanoTime()


推荐阅读