2017-10-10 141 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