差異處
這裏顯示兩個版本的差異處。
java:basic:dateformat [2017/08/19 23:33] |
java:basic:dateformat [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 1: | 行 1: | ||
+ | {{tag>java}} | ||
+ | ====== DateFormat ====== | ||
+ | 提供轉換Date輸出格式或將Date String轉回Date的功能。 | ||
+ | ===== SimpleDateFormat ===== | ||
+ | SimpleDateFormat是最常使用的DateFormat子類別。我們以一個格式轉換的範例做說明:將**2012-04-21T14:08:44.801Z**格式轉為UTC+8時區並以yyyy-MM-dd HH:mm:ss表示。\\ | ||
+ | **2012-04-21T14:08:44.801Z**是RFC3999Date的規格,Z是UTC+0的意思,我們可以使用**yyyy-MM-dd'T'HH:mm:ss.SSS'Z'**來表示此字串格式(並非所有RFC3999Date格式通吃,如果要通吃可參考Resource[[http://cokere.com/RFC3339Date.txt|連結]]的做法)。其中T與Z使用單引號(')括起,以避免被DateFormat誤判。 | ||
+ | <code java> | ||
+ | DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); | ||
+ | df.setTimeZone(TimeZone.getTimeZone("UTC")); // or set GMT | ||
+ | Date date = df.parse("2012-04-21T14:08:44.801Z"); | ||
+ | </code> | ||
+ | 上述程式碼產生的日期輸出為Sat Apr 21 22:08:44 CST 2012。假如沒做setTimeZone,SimpleDateFormat預設會使用你機器上所設定的TimeZone,而從這時間轉成另一個TimeZone時間就會出問題(並非由UTC轉到UTC+8,而是Default TimeZone轉到UTC+8)。而TimeZone的部分可參考以下範例輸出對應,UTC與GMT時間差不了多一般都會被認為是一樣的時間,但TimeZone的getTimeZone只能認得**UTC**、*GMT*、**GMT+Offset**與時區名稱,如果輸入它不認得的名稱就會轉為GMT的TimeZone。 | ||
+ | <code java> | ||
+ | System.out.println(TimeZone.getTimeZone("UTC")); | ||
+ | >sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("UTC+8")); | ||
+ | >sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("ss")); | ||
+ | >sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("GMT+8")); | ||
+ | >sun.util.calendar.ZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("GMT+8:01")); | ||
+ | >sun.util.calendar.ZoneInfo[id="GMT+08:01",offset=28860000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("GMT+8.1")); | ||
+ | >sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] | ||
+ | |||
+ | System.out.println(TimeZone.getTimeZone("America/Los_Angeles")); | ||
+ | >sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]] | ||
+ | </code> | ||
+ | |||
+ | 因此如果我們要將某個時間轉成另外一個格式與時區,可以用下面這個做法: | ||
+ | <code java> | ||
+ | df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
+ | df.setTimeZone(TimeZone.getTimeZone("GMT+08:00")); | ||
+ | System.out.println(df.format(date)); | ||
+ | </code> | ||
+ | |||
+ | 總結一下: | ||
+ | * 使用DateFormat轉換時區時間時,必須注意source所要表達的時區為何,這樣parse後format才不會出問題。我想假如是一個多國使用的軟體,存到資料庫的時間應該會存GMT時區吧? | ||
+ | * TimeZone.getTimeZone操作以GMT為主較佳,如果有明確的地區當然更好,畢竟GMT+8的國家也不少。 | ||
+ | * 格式的詳細對照可以直接參考javadoc,我是每次寫每次查。 | ||
+ | |||
+ | 我遇到有問題的格式是**yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'**,這是使用svn info -xml所產生出來的date格式。但我在使用parse method後,會將SSSSSS的時間進位過去,這裡是我還不解的地方。畢竟S代表毫秒,1000毫秒為1秒,六個S不曉得是表達什麼? | ||
+ | |||
+ | ===== Resource ===== | ||
+ | * [[http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html|DateFormat Javadoc]] | ||
+ | * [[http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html|SimpleDateFormat Javadoc]] | ||
+ | * [[http://www.ietf.org/rfc/rfc3339.txt|RFC 3339 Date Format]] | ||
+ | * [[http://cokere.com/RFC3339Date.txt|RFC 3339 Date Parser]] | ||
+ | |||
+ | ===== ===== | ||
+ | ---- | ||
+ | \\ | ||
+ | ~~DISQUS~~ |