2013-07-03 63 views
3

我目前正在驗證生成的Excel工作表包含正確呈現的「時間戳」,其日期和時間部分在單獨的單元格中,並且其格式通過語言環境進行調整。使用新日期創建Java日期時忽略夏令時(aDate.getTime()+ aTime.getTime())

我的測試用例失敗了,因爲當我從字符串中讀取Excel工作表的時間時,似乎忽略了夏令時。

這裏是我的Java代碼:

Date now = new Date(); 

    // [... other code, creating and reading the Excel sheet etc. ...] 

    // from an Excel sheet 
    String dateString = cellB2.getStringCellValue(); // e.g., 3.7.2013 
    String timeString = cellB3.getStringCellValue(); // e.g., 13:38:09 

    TimeZone tz = TimeZone.getDefault(); // Berlin, CEST 
    dateFormat.setTimeZone(tz); // dateFormat is result of DateFormat.getDateInstance(DateFormat.MEDIUM, locale); e.g. with locale "cs_CZ" 
    timeFormat.setTimeZone(tz); // timeFormat is result of DateFormat.getTimeInstance(DateFormat.MEDIUM, locale); e.g. with locale "cs_CZ" 

    // try to parse the time/date strings using the expected format 
    Date actualDate = dateFormat.parse(dateString); // e.g., Wed Jul 03 00:00:00 CEST 2013 
    Date actualTime = timeFormat.parse(timeString); // e.g. Thu Jan 01 13:38:09 CET 1970 

    // now: e.g. Wed Jul 03 13:38:09 CEST 2013 
    // actualDateTime: e.g. Wed Jul 03 12:48:07 CEST 2013 
    Date actualDateTime = new Date(actualDate.getTime() + actualTime.getTime()); 
    assertFalse(now.after(actualDateTime)); // fails 
+1

首先我不喜歡你解析的方式。我首先要連接兩個輸入字符串(在它們之間有空格),然後只進行一個解析。我不是100%確定當你解析一個沒有日期值的時間時會發生什麼,可能是它將當前日期作爲默認值,還是真的考慮0 + timeConversion?我希望看到什麼actualDate和ActualTime返回,如果你格式化他們...此代碼以前工作? – Martin

+0

不,代碼沒有工作過。 關於僅使用一個解析:我無法找到一種方法從DateFormats中獲取模式而不投射 - 是否有任何? – RobertG

+0

關於解析一個只顯示時間的字符串,你可能是對的:評論顯示actualTime似乎是關閉一個小時(CET而不是CEST),但我想知道是否可以阻止。顯然,setTimeZone()不起作用。 – RobertG

回答

1

繼雙方馬丁和馬特的建議,這是我最後的程序片斷:

// from an Excel sheet 
    String dateString = cellB2.getStringCellValue(); 
    String timeString = cellB3.getStringCellValue(); 

    TimeZone tz = TimeZone.getDefault(); 

    // NEW! 
    DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, l); 
    dateTimeFormat.setTimeZone(tz); 

    Date actualDateTime = dateTimeFormat.parse(dateString + " " + timeString); 
    assertFalse(now.after(actualDateTime)); 
0

設置actualTime後,我必須作出以下區別:

if (tz.inDaylightTime(actualDate)) { 
     actualTime = new Date(actualTime.getTime() + 1000 * 60 * 60); 
    } 

隨着時間的唯一字符串總是會導致一個日期1月1日1970年,夏令時永遠不會考慮(至少不是柏林的情況),我必須手動進行調整。

+2

實際上,在1970年1月1日期間,一些時區*是夏令時。具體來說,英國是BST而不是GMT。 –

+0

謝謝,我改變了答案。 – RobertG

2

羅伯特,

您的解決方案的工作,但我認爲這是喜歡拍各地的另外一個解決方法,它使你的代碼更復雜,因此更難十個分量。爲什麼不使用的SimpleDateFormat使用此模式:

"dd.MM.YYYY kk:mm:ss" 

然後,只需做一個日期字符串是這樣的:

String dateTime = cellB2.getStringCellValue() + " " + cellB3.getStringCellValue(); 

然後你可以解析它...我沒有實際測試它,但它應該給你的想法,也許你需要檢查的模式String,這裏的參考:

http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html

問候

+0

這些模式是我輸入的一部分:它們使用\t DateFormat.getDateInstance(...)和DateFormat.getTimeInstance(...)檢索。但我想我會給DateFormat.getDateTimeInstance(...)一個鏡頭 - 否則,我將不得不將DateFormat轉換爲SimpleDateFormat或其他東西,我不想這樣做。 – RobertG

+0

爲什麼不使用SimpleDateFormat來代替?因此,您可以在構造函數中傳遞該模式,並使其表現得與您需要的一樣。它看起來像這樣SimpleDateFormat dateTimeFormat = new SimpleDateFormat(「dd.MM.YYYY kk:mm:ss」);你不需要施放任何東西...... – Martin

+1

當分別解析時可能會出現其他細微差別,所以我強烈推薦這種方法。例如,如果午夜的日期是模糊的DST回滾轉換的一部分,但在特定時間處於正常狀態,會發生什麼情況?在午夜肯定有時區轉換(例如巴西)。 –

0

日期在Java中不會自動添加日光節約時間。這是因爲java Date是通過epoch(自1970年1月1日以來的秒數)計算出來的,並且表示UTC時間。

如果您希望您正在使用的課程自動更正夏令時,則可以使用內置的Calendar類或Joda Time。我真的建議看看喬達時間。它優於java.util.Date的java.sql.Date和java.util.Calendar的組合!處理一個真正完整的時間庫要比處理三個不同的時間庫更容易,並嘗試在它們之間進行轉換。

此外,正如一個有趣的文章,顯示了DST的難度,請參閱this video - 大約4分鐘時間,它解釋了不同國家如何實施DST以及這對每個人造成的頭痛。