[英]Incorrect date parsing with SimpleDateFormat
我有一個帶有date()和time()列的MySQL表,例如
CREATE TABLE `vol` (
`ID` bigint(20) unsigned NOT NULL,
`DEPART_DATE_VOL` date NOT NULL,
`DEPART_HEURE_VOL` time NOT NULL,
`ARRIVEE_DATE_VOL` date NOT NULL,
`ARRIVEE_HEURE_VOL` time NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我需要在WHERE子句中使用date()查詢行,所以我沒有datetime()或時間戳(此外,我無法修改數據庫)
當在我的DAO中獲取信息時,我會合並日期和時間列以解析Java日期,例如:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
addon.setDateDepart(sdf.parse(rs.getString(DEPART_DATE_VOL) + " " + rs.getString(DEPART_HEURE_VOL)));
addon.setDateArrivee(sdf.parse(rs.getString(ARRIVEE_DATE_VOL) + " " + rs.getString(ARRIVEE_HEURE_VOL)));
對於有出發日期的行:
但對於到達日期:
TMP解決方案
現在,我會堅持
addon.setDateDepart(new LocalDateTime(rs.getString(DEPART_DATE_VOL) + "T" + rs.getString(DEPART_HEURE_VOL)).toDate());
addon.setDateArrivee(new LocalDateTime(rs.getString(ARRIVEE_DATE_VOL) + "T" + rs.getString(ARRIVEE_HEURE_VOL)).toDate());
這似乎可行,但我不確定我是否會遇到時區問題...
在時間部分嘗試使用HH:mm:ss
。 hh
用於“上午/下午(1-12)的小時數”,請參閱javadoc 。
timestamp
數據類型,而不要使用單獨的列作為日期和時間。 MySQL timestamp
采用UTC格式,因此應避免在數據庫端出現任何時區問題。 java.time
(現代的Java日期和時間API)。 諸如Date
類的舊日期和時間類設計欠佳,尤其是SimpleDateFormat
尤其麻煩,因此請避免使用它。 閱讀更多有關此問題的信息:針對地理位置不同的用戶的日期操縱/存儲的Java最佳實踐 。 如果您不能做到所有這些,請盡力而為。
如果可以在數據庫中存儲時間戳,則可以將其作為java.time.Instant
檢索:
Instant departVol = rs.getObject(DEPART_INSTANT_VOL, Instant.class);
如果您無法更改addon.setDateDepart()
接受的類型,請轉換為以下Date
:
addon.setDateDepart(Date.from(departVol));
或在使用ThreeTen Backport的版本中,即java.time
向Java 6和7的java.time
移植:
addon.setDateDepart(DateTimeUtils.toDate(departVol));
如果無法更改數據庫設計,仍然可以從中檢索java.time
對象:
LocalDate departDateVol = rs.getObject(DEPART_DATE_VOL, LocalDate.class);
LocalTime departHeureVol = rs.getObject(DEPART_HEURE_VOL, LocalTime.class);
LocalDateTime departDateHeureVol = LocalDateTime.of(departDateVol, departHeureVol);
轉換為老式Date
很不穩定,因為正如您所說,可能存在時區問題。 嘗試:
addon.setDateDepart(
Date.from(departDateHeureVol.atZone(ZoneId.systemDefault()).toInstant()));
如果此處似乎存在時區問題,則需要指定正確的時區而不是ZoneId.systemDefault()
。
如果您的Java版本或JDBC驅動程序不支持從結果集中獲取正確的日期時間對象,則使用現代類可以很容易地解析字符串:
LocalDate departDateVol = LocalDate.parse(rs.getString(DEPART_DATE_VOL);
LocalTime departHeureVol = LocalTime.parse(rs.getString(DEPART_HEURE_VOL);
與這些對象一樣,繼續進行。
PS我還沒有測試我的代碼段。 如果有錯別字,而您卻不能自己解決,請還原。
kevmo314是正確的是小寫字母hh
在格式模式字符串是與AM或PM小時,從1到12,那么12:20:00
確實意味着00:20:00
。 要在24小時制上解釋12
在一天中的0到23之間使用大寫HH
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.