2017-10-10 127 views
1

我想获取洛杉矶的时区信息,现在10/10/2017是夏令时, 但是当我获得不同的结果时以两种方式在洛杉矶获得时区。java:timezone getTimeZone(“GMT-0700”)'timezone useDaylight不正确

public class TimeZoneDemo2 { 
    public static void main(String[] args) { 
    TimeZone timeZoneLosAngeles = 
    TimeZone.getTimeZone("America/Los_Angeles"); 
    System.out.println(timeZoneLosAngeles); 

    TimeZone timeZoneGmtMinus07 = TimeZone.getTimeZone("GMT-07:00"); 
    System.out.println(timeZoneGmtMinus07); 
    } 
} 

结果是:

sun.util.calendar.ZoneInfo [ID = “美国/洛杉矶”,偏移= -28800000,dstSavings = 3600000,useDaylight =真,过渡= 185, lastRule = java.util.SimpleTimeZone中[ID =美洲/洛杉矶,偏移= -28800000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 3,startMonth = 2,朝九特派= 8,startDayOfWeek = 1,开始时间= 7200000 ,startTimeMode = 0,endMode = 3,endMonth = 10,endDay = 1,endDayOfWeek = 1,endTime = 7200000,endTimeMode = 0]]

sun.util.calendar.ZoneInfo [id =“GMT-07:00 ”,偏移= -25200000,DS tSavings = 0,useDaylight =假,转换= 0,lastRule = NULL]

我的问题是:有关夏令由 “美国/洛杉矶” 获得时区信息的时间信息。为什么不在夏令时信息(useDaylight = false)中包含“GMT -0700”获取的时区信息?

+1

你的意思是'TimeZone.getTimeZone(String)'的结果取决于当前时间是不正确的。 –

+2

GMT-7有多个地点http://www.mapstudio.co.za/wp-content/uploads/2014/02/9781770265646.jpg它如何知道你的意思是洛杉矶的? –

+1

'GMT-07:00'是一个**偏移量**(与UTC不同),而“America/Los_Angeles”是一个**时区**(一组地区在历史中使用的所有偏移量),详细了解区别[这里](https://stackoverflow.com/tags/timezone/info)。如前所述,有超过1个时区[使用相同的偏移量](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets#UTC.E2.88.9207:00.2C_T),所以只有拥有GMT-7时, [不能说哪个时区是](https://stackoverflow.com/q/36629250/7605325) – 2017-10-10 12:54:16

回答

9

我想为洛杉矶的时区信息,现在2017年10月10日是夏令时

所以你应该问的“美国/洛杉矶”区。这就是它的目的。

“GMT-07:00”区域是一个固定偏移区域 - 它只适用于当您要表示“持续时间比UTC晚七个小时的时区”时。 不适用适用于洛杉矶。

有很多其他时区,其中有时是在UTC-7 - 为什么你会期望格林威治标准时间-07:00意味着“在洛杉矶观察到的时区”?换句话说,Java正在做正确的事情 - 这是您对“GMT-07:00”区域意味着不正确的预期。

+2

此外,洛杉矶是UTC-8的一年的一部分;如果您希望Java在使用GMT-7时猜测您的意思是奥尔森编号,那么它是如何知道您不是指丹佛? (或者在其他地方使用-7年的部分时间)。 –

+1

...或凤凰,这是*整个*年的-7。 –

0

Answer by Jon Skeet是正确的,应该被接受。由于许多区域可能同时共享一个偏移量,因此无法可靠地确定UTC偏移量以来的时区。此外,区域的偏移量可能随时间而变化。

下面是一些代码示例,解决了使用比在问题中看到的更现代的类的问题。

java.time

您正在使用的是现在传统麻烦旧日期时间类,由java.time类取代。

正如其他人所说,如果您知道预期的时区,请始终使用该区域而不要仅使用offset-from-UTC。偏移量只是UTC之前或之后的小时,分​​钟和秒数。时区是一个地区人民所使用的偏移量变化的历史。时区知道过去,现在和(暂时)这种偏移变化的未来。

ZoneIdZoneOffset类取代TimeZone

continent/region的格式指定一个proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母缩写,如ESTIST,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("America/Los_Angeles") ; // Or "Africa/Tunis", "Pacific/Auckland", etc. 

获取通过该区域的镜头看到的当前时刻。

ZonedDateTime zdt = ZonedDateTime.now(z) ; // Fetch current moment for that zone. 

提取同一时刻,但调整为UTC。

Instant instant = zdt.toInstant() ; // Extract the same moment but in UTC. 

将某个时刻调整到另一个区域。

ZonedDateTime zdtKolkata = instant.atZone(ZoneId.of("Asia/Kolkata")) ; // Determine same moment, same point on timeline, but in another time zone. 

所有这三个对象都代表时间线上的同一点,但用不同的挂钟时间查看。

查看该地区当时人们在此时使用的偏移量。

ZoneOffset offset = z.getRules().getOffset(instant) ; // Get the offset in place at that moment for that time zone. 

你会发现,2018年,在这一年的一部分America/Los_Angeles偏移会-07:00(断绝小时后面UTC)。在今年的另一部分,抵消将为-08:00(比UTC晚8个小时)。这种抵消的变化是由于政治家决定遵守Daylight Saving Time (DST)


关于java.time

java.time框架是建立在Java 8以后。这些类代替了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore