Java国际化:时区

时间:2020-01-09 10:35:37  来源:igfitidea点击:

本文探讨了如何在Java中使用时区。

当系统用户时,例如Web应用程序具有不同的时区,因此以对所有用户都看似一致的方式来管理系统中的日期和时间可能是一个挑战。我将在本文中介绍这个问题。

世界标准时间

UTC是协调世界时(Universal Time Coordinated?)的缩写。 UTC是英国时区的时间(例如格林威治标准时间)。

时区

所有时区均以相对于UTC时间的偏移量进行计算。例如,丹麦哥本哈根的时区为UTC +1,表示UTC时间加一小时。

夏令时

UTC时间与夏令时无关。这意味着,在夏季,丹麦哥本哈根的时间为UTC + 2,即UTC时间加上两个小时。

UTC中的存储日期和时间

如果应用程序需要在内部存储日期和时间(例如在数据库中),请在存储之前将其转换为UTC时间。当所有日期和时间都存储在UTC中时,搜索给定的日期和时间要容易得多。如果日期和时间存储在数据库的不同时区中,将很难搜索某个日期之前或者之后的所有日期。我们需要在搜索时转换日期和时区,以便与搜索条件的日期进行比较。这实际上是行不通的。

转换时区

用户键入日期和时间时,通常会在自己的时区中输入。如果另一个时区的用户需要查看该日期和时间,则该用户通常希望查看该日期和时间已转换为自己的时区。

在Java中,我们可以使用java.util.Calendar类在时区之间进行转换。这是一个例子:

Calendar calendar = new GregorianCalendar();

calendar.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

calendar.set(Calendar.HOUR_OF_DAY, 12);

System.out.println("UTC: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("UTC: " + calendar.getTimeInMillis());

calendar.setTimeZone(TimeZone.getTimeZone("Europe/Copenhagen"));
System.out.println("CPH: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("CPH: " + calendar.getTimeInMillis());

calendar.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("NYC: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("NYC: " + calendar.getTimeInMillis());

首先,我们创建一个GregorianCalendar实例(Calendar子类)。

其次,将时区设置为UTC。在设置时间之前,我们应该始终设置时区。如果不这样做,那么我们设置的时间(例如一天中的小时)可能会被解释为位于"日历"实例的时区中。当我们以后更改时区时,一天中的小时等会更改时间(一天中的小时)。因此,从时区开始,然后设置时间(毫秒,一天中的小时等)。

第三,我们设置时间。我们可以在任何给定的时区中设置时间(只需先设置时区)。

第四,我们可以将时区更改为所需的目标时区。更改时区后,我们可以看到一天中的小时等可能会更改。此示例在将时区更改为两个不同的时区(都不同于UTC)后,输出一天中的小时。

从此示例打印的输出将是:

UTC: 12
UTC: 1363351520548
CPH: 13
CPH: 1363351520548
NYC: 8
NYC: 1363351520548

请不要这样,无论在"日历"实例上设置的时区如何," Calendar.getTimeInMillis()"总是以UTC返回时间。从上面的输出中可以看到,三个时区之间的一天中的时间有所不同,但是时间以毫秒为单位是相同的。

可用时区ID

如示例所示,我们可以从java.util.TimeZone类中获取时区。为此,我们需要知道时区的ID。这是一个例子:

TimeZone timeZone = TimeZone.getTimeZone("Europe/Copenhagen")
calendar.setTimeZone(timeZone);

在此示例中,时区ID为"欧洲/哥本哈根"。

我们可以使用TimeZone.getAvailableIDs()获得可用时区ID的列表。这是一个例子:

String[] availableIDs = TimeZone.getAvailableIDs();

for(String id : availableIDs) {
    System.out.println("id = " + id);
}

本示例获取所有可用的时区ID,然后将它们打印到" System.out"。然后,我们可以找到符合我们需求的产品。