Java 使用SimpleDataFormat进行不正确的日期分析
我有一个MySQL表,其中包含date()和time()列,如Java 使用SimpleDataFormat进行不正确的日期分析,java,date,simpledateformat,Java,Date,Simpledateformat,我有一个MySQL表,其中包含date()和time()列,如 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 (`
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()或timestamp(另外,我不能修改DB)
在我的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)));
对于具有出发日期的行:
- 2018-02-26 10:50:00生成的Java日期是正确的
- 2018-02-26 12:20:00生成的Java日期设置为2018-02-26T00:20:00
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)的小时数”,时间部分请参见。Tryhh:mm:ss
<代码>hh用于“上午/下午(1-12)时的小时数”,请参阅
时间戳
数据类型,而不是日期和时间的单独列。MySQL时间戳是UTC格式的,因此应该避免数据库端的任何时区问题java.time
,现代java日期和时间API。像date
这样的旧日期和时间类设计得很糟糕,尤其是SimpleDateFormat
是出了名的麻烦,所以要避免它java.time.Instant
检索:
Instant departVol = rs.getObject(DEPART_INSTANT_VOL, Instant.class);
如果无法更改addon.setDateDeeption()
接受的类型,请将其转换为Date
,如下所示:
addon.setDateDepart(Date.from(departVol));
或者在使用Three-Ten Backport的版本中,java.time
到java 6和7的Backport:
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);
转换成老式的日期是不可靠的,因为正如你所说,可能存在时区问题。尝试:
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我还没有测试我的代码片段。如果有错别字,您自己无法修复,请回复
你的代码出了什么问题?
格式模式字符串中的小写字母hh
表示从1到12的AM或PM的小时数。所以12:20:00
的意思是00:20:00
。要在24小时时钟上解释12
,请使用大写的HH
表示从0到23的小时
链接:
时间戳
数据类型,而不是日期和时间的单独列。MySQL时间戳是UTC格式的,因此应该避免数据库端的任何时区问题java.time
,现代java日期和时间API。像date
这样的旧日期和时间类设计得很糟糕,尤其是SimpleDateFormat
是出了名的麻烦,所以要避免它java.time.Instant
检索:
Instant departVol = rs.getObject(DEPART_INSTANT_VOL, Instant.class);
如果无法更改addon.setDateDeeption()
接受的类型,请将其转换为Date
,如下所示:
addon.setDateDepart(Date.from(departVol));
或者在使用Three-Ten Backport的版本中,java.time
到java 6和7的Backport:
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);
转换成老式的日期是不可靠的,因为正如你所说,可能存在时区问题。尝试:
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我还没有测试我的代码片段。如果有错别字,您自己无法修复,请回复
你的代码出了什么问题?
格式模式字符串中的小写字母hh
表示从1到12的AM或PM的小时数。所以12:20:00
的意思是00:20:00
。要在24小时时钟上解释12
,请使用大写的HH
表示从0到23的小时
链接:我建议您避免使用
SimpleDataFormat
类。它不仅早已过时,而且还出了名的麻烦。今天我们有了更好的功能。您使用的是hh
,这是一种基于12小时的时钟。使用kk
代替24小时时钟。但是,是的,您应该尝试使用java.time
。)在您的工作环境中,您使用的是来自Joda Time的LocalDateTime
?这已经比旧的Java日期和时间类好了,很难理解为什么会有这样的行为。我也很好奇。我想到的是同步,尽管代码中没有多个线程(应该怪DAO吗?)。日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部对其进行同步。我真的很想知道你的例子中是否有这种情况