H2DB 和 Java,大约 > 两个小时的差异
Posted
技术标签:
【中文标题】H2DB 和 Java,大约 > 两个小时的差异【英文标题】:H2DB and Java, an approximate> two hour discrepancy 【发布时间】:2012-09-16 07:27:10 【问题描述】:我正在开发一个比赛计时系统,在某些情况下,我需要从 H2DB 中检索一个时间对象。像它的兄弟(或姐妹)一样,时间数据类型是相对于 1970 年 1 月 1 日,并以 SQL 中的“hh:mm:ss”格式表示,日期默认设置为 01-01-1970。默认情况下,它映射到“java.sql.Time”对象。作为一个值得信赖的学徒,为了显示目的,我编写了以下代码来区分小时和分钟。
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 的时间处理很臭,因为这些函数输出了意外的值,例如,我的数据库中的以下语句给出了 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');
检索:
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"));
显示:
if(race.getCutOffTime()!=null)
long cutOffHour=(int)(race.getCutOffTime().getTime())/(3600000);
RacesCutOffLength.setText(cutOffHour+"");
int cutOffMinute=(int)(race.getCutOffTime().getTime()%(60*60*1000));
this.RacesMinutes.setText(cutOffMinute+"");
else
RacesCutOffLength.setText("0");
RacesMinutes.setText("0");
编辑:我决定用长原语替换 Time 对象
【问题讨论】:
“臭”?好工匠不怪工具…… 两个小时的差异很可能是因为您处于 GMT+2 时区。 那么为什么 Stack-Overflow 中每次提到 Java 时间都至少有一个或多个引用 Joda 时间? :P 这是因为将日期抽象为特定的毫秒数一般不能很好地处理时间段。给定足够的假设,它可以工作得足够好。您的问题似乎是对如何在 Java 和 SQL 日期表示之间进行映射的理解不正确。 @ThorbjørnRavnAndersen Yip。我是个白痴。但这也是时区的问题。我决定在这一刻使用 long 而不是其他时间,我必须将它映射到我的语言环境的时区。 formatter.applyLocalisedFormat("HH:mm"); 【参考方案1】:java.util.Date
始终是 UTC 时间。因此,根据您的语言环境,可能会有一个偏移量。
我听说Joda Time
是一种更好的处理时间的Java API。
无论如何,问题来自于混合了由java.util.Date
处理的日期和其他直接作为 SQL 的一部分传递的日期。
只要您继续对所有内容使用java.util/sql.Date
(并且您不在数据库内达到峰值)(并且您不更改语言环境),结果将是一致的。当您的 SQL 尝试将值直接作为文本传递时,麻烦就开始了。因此,要么在任何地方使用Date
,要么正如垃圾神所说,每次使用Date
时,都要注意将区域设置设置为“GMT”(因此内部表示和日期的输出是相同的)。请注意,这确实包括从数据库返回的Date
【讨论】:
设置格式化程序的时区,显示为here。 我听说过 Joda Time,但是由于这个项目的限制,使用外部库,尤其是大于 3 MB 的库是不被接受的。 只要您继续使用java.util/sql.Date
处理一切(并且您不会在数据库中达到峰值)(并且您不会更改语言环境),结果将连贯。当您的 SQL 尝试将值直接作为文本传递时,麻烦就开始了。因此,要么使用Date
一切,要么正如垃圾神所说,每次使用Date
时,都要注意将语言环境设置为“GMT”(因此Date
的内部表示和输出是相同的)。请注意,这确实包括从数据库返回的Date
。
另一种选择是更改您在数据库中管理Date
的方式;要么在 SQL 中设置它们的值,如 DB #dd/MM/yyyy#
用于 Access 等),要么直接将它们存储为字符串。但是你会失去很多灵活性。
@SJuan76,如果您发表评论并获得三票,我会接受它以上是关于H2DB 和 Java,大约 > 两个小时的差异的主要内容,如果未能解决你的问题,请参考以下文章