2013-10-10 21 views
8


的時間和返回日期是正確的除了的小時,這比它應該是什麼少1小時。

我似乎設置是需要得到正確的時間和日期的一切:爲什麼Calendar會在正確的時區返回錯誤的小時?

- I'm using Calendar.getInstance(), instead of new Date() 
- I'm setting the timezone of the Calendar instance with Timezone.getTimeZone 
- I'm using DateFormat and SimpleDateFormat to format the output 


我的時區是Eastern Standard Time,又名UTC/GMT-5:00無這些線都是有任何影響:

- cal.setTimeZone(TimeZone.getTimeZone(cal.getTimeZone().getDisplayName())); 
- cal.setTimeZone(TimeZone.getTimeZone("EST")); 
- cal.setTimeZone(TimeZone.getTimeZone("UTC")); 
- cal.setTimeZone(TimeZone.getTimeZone("GMT")); 
- cal.setTimeZone(TimeZone.getTimeZone("GMT-5:00")); 

...但這些選項的設置我想要的時區。


這裏是我的嘗試,在那裏我錯誤地將1小時的 Calendar實例:

PrintWriter output = null; 

try { 
    output = new PrintWriter(
    new BufferedWriter(new FileWriter("output.txt", true))); 

    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy"); 
    Calendar cal = Calendar.getInstance(); 

    // ...doesn't seem to be working: 
    cal.setTimeZone(TimeZone.getTimeZone(cal.getTimeZone().getDisplayName())); 

    /* 
    * adding an extra hour here, to make up for the incorrect hour value??? 
    * ...without this line, everything is correct except the hour = n - 1: 
    */ 
    //cal.setTimeInMillis(cal.getTimeInMillis() + (1000 * 60 * 60)); 

    // printing to console here: 
    System.out.println(dateFormat.format(cal.getTime())); 
    System.out.println(cal.getTimeZone().getDisplayName()); 

    // printing to the log-file here: 
    output.println(dateFormat.format(cal.getTime())); 
    output.println(cal.getTimeZone().getDisplayName()); 

} catch (IOException e) { 
    e.printStackTrace(); 

} finally { 
    if (output != null) { 
    output.close(); 
    } 
} 


輸出:

10:05:43:543 10/10/2013 
GMT-05:00 

WRONG - 它應該是11:05:43:543! (附註: - 我很遺憾不能使用Joda-Time

+0

夏令時? – John

+0

@John - 我不知道,很好的問題......今年的夏令時期顯然從3月10日星期日開始,到11月3日星期日結束。可以'日曆'和/或'時區'*不*佔據這個? –

+2

中有鏈接的答案: http://stackoverflow.com/questions/10545960/how-to-tackle-daylight-savings-using-timezone-in-java 希望這會有所幫助。 – guanda

回答

3

1)設置時區(SimpleDateFormat)

2)使用UTC或「真實」時區(如「奧地利/維也納」);
(國家名稱和TimeZone中最大的城市查找它肯定)
EST(= UTC-5)不是一個非常適合計算目的的時區,因爲它是沒有夏時制的時間。

來自中歐的另一個例子:
在冬天,我們使用MEZ(CET),在夏季(夏令時)我們使用(MESZ = CEST)。
但是你想你的電腦caluclates爲你,所以不要使用:

時區的地理poilitical,需要國家的therfore名稱。 (如:俄羅斯前一段時間,而西班牙現在正在討論)
每個國家可以決定改變其時區時,他們想

+0

謝謝@AlexWien,''America/New_York「'適用於我的情況。我想知道,爲什麼像'EST'這樣的時區是一個可以接受的參數?如果它不考慮夏令時? –

+1

可能是因爲它是一個時區,不幸的是,整個一年都沒有人是瓦勒。也有可能存在不使用夏令時的國家 – AlexWien

1

日曆不考慮夏令時。

根據這個帖子:How to tackle daylight savings using Timezone in java

的3字母縮寫須對TZDB區ID來全心全意避免。 EST是東部標準時間 - 標準時間從不觀測DST;它不是一個完整的時區名稱。這是用於部分時區的名稱。 (不幸的是我還沒有碰到過個好詞,這個「半時區」的概念。)

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));

這是一個良好的開端:http://download.java.net/jdk8/docs/api/java/time/ZoneId.html

+0

這是一個可能的評論或更好的改善你的答案! –

0


對於後人,這是我立足崗位「How to tackle daylight savings using Timezone in java」改進的代碼:

PrintWriter output = null; 

try { 
    output = new PrintWriter(
     new BufferedWriter(new FileWriter("output.txt", true))); 

    // here are the relevant changes (a lot less code!): 
    TimeZone zone = TimeZone.getTimeZone("America/New_York"); 
    SimpleDateFormat simpleFormat = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy"); 
    simpleFormat.setTimeZone(zone); 

    // printing to console here: 
    System.out.println(simpleFormat.format(new Date())); 
    System.out.println(simpleFormat.getTimeZone().getDisplayName()); 

    // printing to the log-file here: 
    output.println(simpleFormat.format(new Date())); 
    output.println(simpleFormat.getTimeZone().getDisplayName()); 

} catch (IOException e) { 
    e.printStackTrace(); 

} finally { 
    if (output != null) { 
    output.close(); 
    } 
} 


請注意,我使用SimpleDateFormatDateFormat代替,定製輸出格式(不需要同時使用)。

+1

爲了防止有人遇到此問題,此處使用的日期和時間格式(HH:mm:ss:ms MM/dd/yyyy)並不總是有效。這取決於你如何以及在哪裏存儲這個。以日期時間的形式存儲在MySQL數據庫中,例如,需要使用(yyyy-MM-dd HH:mm:ss)。這裏的例子只是記錄到一個文件或控制檯,所以使用的格式是好的。 – Blizzardengle

相關問題