測試的方式,一樣使用固定的字串作為時間的參數,並且以 System.out.println() 方便觀察結果。基於觀察原生 Java 類別的目的,所以完全不使用 Joda-Time 相關類別,下面是最開始的程式…
public static void main(String[] args) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); Date date = sdf.parse("2013-12-26 18:48:24 UTC"); System.out.println(date); } catch (Exception ex) { ex.printStackTrace(); } }
輸出…
Fri Dec 27 02:48:24 CST 2013從這裡可以發現到在解析的過程中,時區參數是被納入考量的。因此 UTC(+0)的時間在輸出時被加了 8 個小時,成為中原標準時間,這就達到某種程度的轉換效果。不過這種作法的問題,在於時區的表示其實並非唯一。以中原標準時間(China Standard Time)的縮 CST 為例,也可能代表了澳洲中部時間(Central Standard Time)或 中部標準時區(北美洲),Central Standard Time (North America)甚至是 古巴標準時間 Cuba Standard Time。再加上由資料庫取出的時間字串不見得帶有這樣的縮寫,因此,還是把字串裡的時區資訊拿掉,程式改成這樣…
public static void main(String[] args) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse("2013-12-26 18:48:24"); System.out.println(date); } catch (Exception ex) { ex.printStackTrace(); } }
輸出…
Thu Dec 26 18:48:24 CST 2013這樣就是直接把字串轉時間,沒有任何轉換的效果。
查了官方的文件,發現 Date 類別並沒有設定時區方法,而 Calendar 類別所作的,也只有在解析上可以設定時區,就和第一個例子一樣,最終還是在輸出的時候被轉換為系統的時區。再研究一陣子發現,有個 TimeZone 類別帶有 setDefault 的方法,似乎可以進行調整,因此把程式改成下面這樣…
public static void main(String[] args) { try { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // 多加了這一行 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse("2013-12-26 18:48:24"); System.out.println(date); } catch (Exception ex) { ex.printStackTrace(); } }
輸出…
Thu Dec 26 18:48:24 UTC 2013發現輸出的時區改變了,那麼,如果在解析完字串之後,再改變時區。是不是就達到改變時區的效果呢?再多加了兩行程式看看…
public static void main(String[] args) { try { TimeZone.setDefault(TimeZone.getTimeZone("UTC")); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse("2013-12-26 18:48:24"); System.out.println(date); TimeZone.setDefault(TimeZone.getTimeZone("Asia/Taipei")); // 對時區再作一次轉換 System.out.println(date); // 再次輸出結果作為比較 } catch (Exception ex) { ex.printStackTrace(); } }
輸出…
Thu Dec 26 18:48:24 UTC 2013 Fri Dec 27 02:48:24 CST 2013由結果可以看得出來,不單單是時區改變了,連時間也變成 +8 小時的中原標準時間。猜想 Date 物件本身可能不帶有時區資訊,只有在輸出的時候才會參考 TimeZone 類別裡的設定值。因此,在解析時間的前後去調整預設時區的設定,就可以簡單的作到不同時區時間轉換的效果。
我認為,如果是單獨執行的程式,雖然這種作法滿瞎的,但也不失為一個轉換時間的方法。但是情境變成在 Servlet 上運作,如果在多個網路要求同時被處理的狀態下改變 TimeZone 的設定,那就可能導致在另一個執行緒裡的時間解析或輸出異常,因而不可被使用。我想,這種無法被使用在不同狀況的結果,可能是其中一個讓 Joda-Time 的作者覺得原生的 Date 相關類別設計得很蠢的原因吧!
沒有留言:
張貼留言