H2DB和Java,近似值>;两小时不符
我正在开发一个比赛计时系统,在一些情况下,我需要从H2DB中检索一个时间对象。与bretheren(或sisteren)一样,时间数据类型与1970年1月1日相关,并以“hh:mm:ss”格式用SQL表示,默认情况下,日期设置为1970年1月1日。它默认映射到“java.sql.Time”对象。作为一名值得信赖的学徒,我对以下内容进行了编码,将小时与分钟分开,以便于显示H2DB和Java,近似值>;两小时不符,java,sql,time,h2,Java,Sql,Time,H2,我正在开发一个比赛计时系统,在一些情况下,我需要从H2DB中检索一个时间对象。与bretheren(或sisteren)一样,时间数据类型与1970年1月1日相关,并以“hh:mm:ss”格式用SQL表示,默认情况下,日期设置为1970年1月1日。它默认映射到“java.sql.Time”对象。作为一名值得信赖的学徒,我对以下内容进行了编码,将小时与分钟分开,以便于显示 if(race.getCutOffTime()!=null){ long cutOffHour=(race.getC
if(race.getCutOffTime()!=null){
long cutOffHour=(race.getCutOffTime().getTime())/(3600000);
int cutOffMinute=(int)(race.getCutOffTime().getTime()%(60*60*1000));
System.out.println(cutOffHour+":"+cutOffMinute);
}
然而,Java的时间处理臭味出现在这些函数输出意外的值,例如,MyDB中的以下语句给出了3:30的输出
INSERT INTO MagEye.Races(RaceName, EventID,CutOffTime)
VALUES ('TEST', SELECT EventID FROM MagEye.Events
WHERE EventName='Sabrina Love',TIME '5:50:00');
将此语句更改为反映“0:0:0”的时间,则我的值为“-2:00”
我做错了什么?(提前)谢谢你
按要求编辑,以下是我的数据库代码:
表创建语句:
CREATE TABLE IF NOT EXISTS MagEye.Races (RaceID INT PRIMARY KEY AUTO_INCREMENT , RaceName VARCHAR(100) ,EventID INT, Description TEXT, MaxEntrants INT, MinAge INT, MaxAge INT, RacePrefix VARCHAR (5), TimingMethod CHAR(1), CutOffTime TIME, RaceEnd TIMESTAMP,Finished BOOLEAN DEFAULT FALSE, Autostart BOOLEAN, FOREIGN KEY(EventID) REFERENCES MagEye.Events(EventID));
INSERT INTO MagEye.Races(RaceName, EventID,CutOffTime) VALUES ('TEST', SELECT EventID FROM MagEye.Events WHERE EventName='Sabrina Love',TIME '5:50:00');
插入语句:
CREATE TABLE IF NOT EXISTS MagEye.Races (RaceID INT PRIMARY KEY AUTO_INCREMENT , RaceName VARCHAR(100) ,EventID INT, Description TEXT, MaxEntrants INT, MinAge INT, MaxAge INT, RacePrefix VARCHAR (5), TimingMethod CHAR(1), CutOffTime TIME, RaceEnd TIMESTAMP,Finished BOOLEAN DEFAULT FALSE, Autostart BOOLEAN, FOREIGN KEY(EventID) REFERENCES MagEye.Events(EventID));
INSERT INTO MagEye.Races(RaceName, EventID,CutOffTime) VALUES ('TEST', SELECT EventID FROM MagEye.Events WHERE EventName='Sabrina Love',TIME '5:50:00');
检索:
raceDB.result = raceDB.state.executeQuery("SELECT * FROM MagEye.Races WHERE EventID=" + eventID + " ORDER BY RaceName");
java.util.ArrayList<Race> races = new java.util.ArrayList<>();
while (raceDB.result.next()) {
Race thisRace;
String timingMethodString = raceDB.result.getString("TimingMethod");
Race.TimingMethod timingMethod = null;
if (timingMethodString != null) {
timingMethod = Race.TimingMethod.valueOf(timingMethodString);
} else {
timingMethod = Race.TimingMethod.MANUAL;
}
thisRace = new Race(raceDB.result.getInt("RaceID"), event, raceDB.result.getString("RaceName"), raceDB.result.getString("Description"), raceDB.result.getInt("MaxEntrants"), raceDB.result.getInt("MinAge"), raceDB.result.getInt("MaxAge"), raceDB.result.getString("RacePrefix"), timingMethod,(raceDB.result.getTime("CutOffTime")), raceDB.result.getBoolean("Autostart"));
thisRace = new Race(raceDB.result.getInt("RaceID"), event, raceDB.result.getString("RaceName"), raceDB.result.getString("Description"), raceDB.result.getInt("MaxEntrants"), raceDB.result.getInt("MinAge"), raceDB.result.getInt("MaxAge"), raceDB.result.getString("RacePrefix"), timingMethod,(raceDB.result.getTime("CutOffTime")), raceDB.result.getBoolean("Autostart"));
编辑:我决定用一个长的primative替换Time对象
java.util.Date
始终是UTC时间。因此,根据您的区域设置,可能会有一个偏移量
我听说过Joda Time
是一种更好的处理时间的Java API
无论如何,问题来自于混合使用java.util.Date
处理的日期和其他作为SQL一部分直接传递的日期
只要您继续对所有内容使用
java.util/sql.Date
(并且您没有在数据库中达到峰值)(并且您没有更改区域设置),结果将是一致的。当SQL试图将值直接作为文本传递时,问题就会出现。因此,要么到处使用Date
,要么像垃圾神说的那样,每次使用Date
时,都要注意将区域设置设置为“GMT”(因此日期的内部表示和输出是相同的)。请注意,这确实包括从DB返回的Date
设置格式化程序的时区,如图所示。我听说过Joda time,但是由于对该项目的限制,使用外部库,尤其是那些大于3MB的文件是不受欢迎的。只要你对所有文件都使用java.util/sql.Date
(并且你没有在数据库中达到峰值)(并且你没有更改区域设置),结果就会一致。当SQL试图将值直接作为文本传递时,问题就会出现。因此,要么使用Date
一切,要么像垃圾神说的那样,每次使用Date
时,都要注意将区域设置设置为“GMT”(因此日期的内部表示和输出是相同的)。请注意,这确实包括从数据库返回的Date
。另一种选择是更改您在数据库中管理Date
的方式;在SQL中设置它们的值,如DB#dd/MM/yyyy#
用于访问等),或者直接将它们存储为字符串。但是你会失去很多灵活性。@SJuan76,如果你用三张赞成票发表你的评论,我会接受它“臭”?优秀的工匠不会责怪工具……两个小时的差异很可能是因为您处于GMT+2时区。那么,为什么堆栈溢出中每次提到Java时间都至少有一个或多个Joda时间的引用??:p这是因为将日期抽象为特定的毫秒通常不适合处理时间段。如果有足够的假设,它可以工作得很好。您的问题似乎是对如何在Java和SQL表示的日期之间映射的理解不正确。@Thorbjørnravandersen Yip。我是个白痴。但这也是时区的问题。我决定在这一刻使用long,而在其他时候,我必须将它映射到我所在地区的时区。applyLocalisedFormat(“HH:mm”);