日期/時間的國際化,不只涉及到地理位置(Locale,好比星期、月份等日曆本地化表示),還涉及到時區(TimeZone,針對UTC/GMT的偏移量)。時區不只是地理位置規定,更是政治規定,好比中國從地理位置上跨5個時區,但只使用一個統一時區(id=Shanghai/Asia)。 javascript
優先使用用戶確認的locale/timezone/format。不然使用應用系統默認,必須顯示時區,好比amazon的限時銷售顯示爲PST時區。 html
DateFormat df = new SimpleDateFormat(pattern, userLocale);
df.setTimeZone(userTimeZone);
Date userInputDate = df.parse(inputDate);
同一服務系統內全部主機的操做系統、數據庫、JVM,原則上應該使用相同時區。 java
同一服務系統跨時區服務的,日期/時間數據必須帶有時區信息。服務系統之間交換日期/時間數據的,必須帶有時區信息。 mysql
同一服務系統內,數據庫服務器按照其服務的地理位置和時區設置,應用服務器參照數據庫服務器設置。數據庫軟件系統和JVM默認時區不作調整,均採用主機操做系統時區。 web
全部主機開啓NTP,應用服務器向數據庫服務器請求時間同步。 spring
字段類型 |
字節 |
精度 |
範圍 |
說明 |
---|---|---|---|---|
date | 3 |
天 |
'1000-01-01' to '9999-12-31' | 日期 |
datetime | 8 |
秒 |
'1000-01-01 00:00:00' to '9999-12-31 23:59:59' | 日期和時間混合 |
timestamp | 4 |
秒 |
'1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. | 日期和時間混合,轉換爲UTC時區的時間後存儲;insert/update時,由數據庫自動更新。 |
year | 1 |
年 |
1901 to 2155, or 0000 | 年份 |
time | 3 |
秒 |
'-838:59:59' to '838:59:59' | 時間值或持續時間 |
說明: sql
字段類型 | 字節 |
精度 |
範圍 |
說明 |
---|---|---|---|---|
date |
7 |
秒 |
-4712-01-01 00:00:00 to 9999-12-31 23:59:59 | 日期和時間混合 |
timestamp(n) | 7-11 | 秒~納秒 |
秒範圍同上 | 日期和時間混合,小數秒位數(0-9,至關於秒-納秒)可設置 |
timestamp WITH TIME ZONE | 9-13 |
秒~納秒 | 秒範圍同上 | 日期和時間混合,同時存儲時區。若輸入不指定時區,則使用數據庫時區 |
timestamp WITH LOCAL TIME ZONE | 7-11 | 秒~納秒 | 秒範圍同上 | 轉換爲數據庫時區後存儲,不存儲時區 |
interval year to month | 5 | N/A | N/A | 存儲年或月指定的時間段 |
interval day to second | 11 |
N/A | N/A |
存儲天,小時,分鐘,秒指定的時間段 |
說明: 數據庫
字段類型 | 字節 | 精度 |
範圍 |
說明 |
---|---|---|---|---|
smalldatetime | 4 |
分 |
1900-01-1 00:00:00 to 2079-06-06 23:59:00 | 日期和時間混合 |
datetime | 8 | 3.33毫秒 |
1753-01-01 00:00:00.000 to 9999-12-31 23:59:59.998 | 日期和時間混合 |
datetime2(n) | 6-8 | 100ns | 0001-01-01 00:00:00.0000000 to 9999-12-31 23:59:59.9999999 | 日期和時間混合。n爲小數秒精度,取值範圍爲0-7,表示1秒-100ns |
date | 3 | 天 |
001-01-01 to 9999-12-31 | 日期 |
time(n) | 3-5 | 100ns | 00:00:00.0000000 to 23:59:59.9999999 | 時間。n爲小數秒精度,取值範圍爲0-7,表示1秒-100ns |
datetimeoffset | 8-10 |
100ns | 0001-01-01 00:00:00.0000000 to 9999-12-31 23:59:59.9999999 | 日期和時間混合。n爲小數秒精度,取值範圍爲0-7,表示1秒-100ns。 數據庫時區與UTC的時區偏移量(精確到分鐘)被存儲。 |
jdbc使用java.util.Date的三個子類(見上圖),負責與數據庫系統交互。java.sql.Date只包含日期,java.sql.Time只包含時間,java.sql.Timestamp包含日期和時間混合,精確到納秒。java type, jdbc sql type和數據庫字段類型對應關係以下: apache
java.sql |
java.sql.Types |
mysql |
sqlserver |
oracle |
---|---|---|---|---|
Date |
DATE |
date |
date |
date |
Time |
TIME |
time |
time |
date |
Timestamp |
TIMESTAMP |
datetime timestamp |
datetime datetime2 datetimeoffset |
date timestamp [with ....] |
String |
VARCHAR | timestamp WITH TIME ZONE |
當檢索列時,返回給用戶的值被轉換成 TIME_ZONE 會話參數指定的時區(JVM報告的當前時區:TimeZone.getDefault(),來自-Duser.timezone的設定或主機操做系統時區,或設置TimeZone.setDefault(timezone))。 json
當設置列時(PreparedStatement.setTimestamp):設置的值將被轉換成 TIME_ZONE 會話參數指定的時區。
mybatis關於日期/時間處理的地方,主要是使用TypeHandler:
register(Date.class, new DateTypeHandler()); register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler()); register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler()); register(JdbcType.TIMESTAMP, new DateTypeHandler()); register(JdbcType.DATE, new DateOnlyTypeHandler()); register(JdbcType.TIME, new TimeOnlyTypeHandler()); register(java.sql.Date.class, new SqlDateTypeHandler()); register(java.sql.Time.class, new SqlTimeTypeHandler()); register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());
各個TypeHandler主要處理java.util.Date類型和jdbc sql type的映射關係和轉換,屏蔽java.sql.Date/Time/Timestamp的差別。好比:
<resultMap ... > <result column="createTime" property="createTime" jdbcType="TIMESTAMP" /> </resultMap> <select ...> select ... from ... where ... <![CDATA[ and createTime>= #{start,jdbcType=TIMESTAMP} and createTime<#{end,jdbcType=TIMESTAMP} ]]> </select>
struts2/spring3 mvc針對日期/時間處理和國際化方面,主要涉及到攔截器設置locale上下文環境、日期/時間字符串輸入解析、驗證、國際化顯示這幾個方面。
二者均將獲取到的locale暴露到request scope context中,供解析、國際化使用。二者均缺少TimeZone相關的攔截器。若是單點登陸系統增長了用戶profile管理,則還能夠增長基於profile的攔截器實現。
兩個框架都利用DateFormat的parse方法進行解析,支持locale/timezone轉換。
在沒法獲知用戶locale/timezone的狀況下,或者用戶輸入格式隨意,經過猜想來解析用戶的時間含義,是不夠準確的。spring框架把這個決定權交給開發者,很明智。所以,在涉及到用戶輸入時,必須明確規範用戶的輸入格式、協商用戶時區。
在輸入解析時進行了日期/時間格式合法性驗證後,二者的驗證框架,均有針對日期/時間的能否爲空、範圍驗證。
都可以在二者支持的模板系統中添加相關的宏或tag。實際格式化由暴露在view context中的DateFormat幫助類,根據request scope context中的locale/timezone或缺省設置來處理。
xml/json也被MVC框架用來做爲視圖層。更多的時候,用做兩個系統進行信息交互(好比webservice和rest)的一種中間格式。
JAXB規範中的日期/時間格式,遵循XML中的日期/時間規範(ISO8601),JDK內部實現中格式以下:
JSON規範並無定義如何序列化日期時間。json框架主要處理方式以下: