Java:从数据库到毫秒的日期/时间,小时消失

时间:2014-02-06 17:06:17

标签: java mysql date datetime

我遇到了日期和时区的问题。

我有一个MySQL InnoDB数据库,它包含两个字段DATE(yyyy-MM-dd)TIME(HH:mm:ss)。这些被称为UTC (0 GMT)。我的电脑位于CET (+1 GMT)

dateObject是此resultSet.getTime("date_field")java.sql.Date)的结果

timeObject是此resultSet.getDate("time_field")java.sql.Time

的结果

在数据库中,DATE存储为2014-02-22和TIME 15:00

System.out.println("Untouched "+dateObject+" "+timeObject);

long date = dateObject.getTime();
long time = timeObject.getTime();

System.out.println("Touched "+new Date(date+time));

结果如下:

Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 14:00:00 CET 2014

为什么从触摸输出跳过一小时?我期待以下内容:

Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 15:00:00 CET 2014

为了隆隆作响,我也尝试了以下内容:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date(date+time)));

结果:

2014-02-22 14:00:00

总而言之。我期待GMT + 1显示16:00(本地),GMT + 0显示15:00

2 个答案:

答案 0 :(得分:1)

我想我确实回答了ma问题(请记住,db中的timeObject是UTC时间的15:00:00):

TimeZone tz = TimeZone.getTimeZone("Gmt0");
SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdfFull.setTimeZone(tz);

Date updateDate = sdfFull.parse(dateObject.toString()+" "+timeObject.toString());

System.out.println(updateDate);

我希望得到的结果:

Sat Feb 22 16:00:00 CET 2014

答案 1 :(得分:0)

原因与此SO-answer类似。但请注意有关toString()的详细信息。

java.util.Date.toString() => output dependent on your system time zone
                             in format pattern "EEE MMM dd HH:mm:ss zzz yyyy"

java.sql.Date.toString() => output in format "yyyy-MM-dd" (your dateObject)
java.sql.Time.toString() => output in format "HH:mm:ss" (your timeObject)

sql表示不依赖于时区。所以你比较苹果和桃子。

补充说明:

我在测试方面投入了更多,并找到了:

java.sql.Date dateObj = new java.sql.Date(2014 - 1900, Calendar.FEBRUARY, 22);
Time timeObj = new Time(15, 0, 0);
Time midnight = new Time(0, 0, 0);
Date d = new Date(dateObj.getTime() + timeObj.getTime());

System.out.println("dateObj: " + dateObj + "/" + dateObj.getTime()); 
// dateObj: 2014-02-22/1393023600000, one hour less than a full day because of UTC-long

System.out.println("timeObj: " + timeObj + "/" + timeObj.getTime()); 
// timeObj: 15:00:00/50400000 => one hour less as UTC-long

System.out.println("midnight: " + midnight + "/" + midnight.getTime()); 
// midnight: 00:00:00/-3600000 => one hour less, negative!

System.out.println(new Date(dateObj.getTime())); // Sat Feb 22 00:00:00 CET 2014
System.out.println(new Date(timeObj.getTime())); // Thu Jan 01 15:00:00 CET 1970
System.out.println(d); // Sat Feb 22 14:00:00 CET 2014

所以我强烈怀疑以下效果:dateObject和timeObject都是根据系统时区计算的,因此它们的utc-long值显示两个小时 - 时区偏移量。如果你只是在一个Date-object中合并两个,那么两个增量中的一个会丢失,因为一个日期对象不能考虑两个偏移。

结论:你试图通过总结他们的utc-long来结合日期和时间,但这通常是错误的方法。 日期加日期不是日期,但未定义!在特定于域的语言中,您只能将持续时间/句点添加到日期/时间。因此,具有午夜对象的解决方案可以是:

Date d = new Date(dateObj.getTime() + timeObj.getTime() - midnight.getTime());
System.out.println(d); // Sat Feb 22 15:00:00 CET 2014, correct - what you wanted