0

我想在应用程序中设置任意时间。时间以毫秒格式从服务器下载 - 它应该独立于locale其他系统首选项。但是应用程序重新获得线程安全解决方案,并且对象像标准而不是线程安全Calendar对象。

什么是最好的方法?

今天我使用:

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(serverTime);

但对我来说不是好方法,因为它不是线程安全的。

tl;dr 程序必须包含自己的内部时钟,从外部服务器获取时间。时钟必须是线程安全的。

4

3 回答 3

1

Java 应用程序使用的时间(以毫秒为单位)是

自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。

此数字基于 GMT 时区。如果您需要在另一个时区打印它,您可以使用任何您想要的格式化类,比如SimpleDateFormat. 如果您需要使保持它的变量成为线程安全的,只需对其进行同步,可能通过将其包装在一个类中。

public class TimeInMillis {
    private volatile long time;

    public void setTime(long time) {this.time = time;} 

    public time getTime() {return time;}
}

每当您需要显示它时,只需获取TimeInMillis对象,获取time并使用它创建一个Calendar对象。然后使用格式化类以您需要的格式、区域设置、时区打印时间。

于 2013-09-08T21:04:39.960 回答
0

时间以毫秒格式从服务器下载 - 它应该独立于区域设置和其他系统首选项

那不是“时间”。这是一个时间戳,意味着特定软件在特定时间点报告的特定时间值。

现在,如果您想说的是,在未来与该服务器的通信中,您希望将设备报告的时间转换为服务器已知的时基,至少有点道理。在这种情况下,您将计算收到时间戳时的设备时间与时间戳本身中的时间值之间的差值。然后,将该增量应用于您向服务器报告的未来时间。

程序必须包含自己的内部时钟,从外部服务器获取时间

这没有任何意义。

在这个宇宙中,根据我们目前的物理学知识,时间是连续的和线性的。只有当您“从外部服务器获取时间”时,时间才不会改变。同样,您“从外部服务器获取...”是时间戳,是服务器上的时钟认为您发出请求时的时间的声明。您可以使用该时间戳与来自该服务器的其他时间戳进行比较,并且您可以使用该时间戳与设备的当前时间进行比较以确定差异。

但是,您无法在 Java 代码中创建硬件,因此您无法在 Java 代码中创建“内部时钟”。唯一的时钟是设备的时钟。如前所述,您可以通过应用上述差异设备时钟的时间转换为服务器的时基,但时间的流逝仍由设备自己的时钟标记。

由于差异将是intor long,您可以使用AtomicIntegerorAtomicLong如果您担心多个线程同时使用该值。

于 2013-09-08T21:24:36.107 回答
-1

I would just the the time in milli-second with GMT (BTW computers don't support UTC as such)

long serverTime = System.currentTimeMillis(); // millis since 1/1/1970 GMT.

To get/set this in a thread safe manner you can make it volatile

BTW Calender is pretty slow even on a PC. I would avoid using it on a phone.

于 2013-09-08T20:57:12.720 回答