2014-02-06 4 views
3

У меня проблема с датами и часовыми поясами.Java: Дата/Время от базы данных до миллисекунд, исчезает час

У меня есть база данных 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

+0

потому что ваша машина находится в другом часовом поясе. – Sionnach733

+0

Не могли бы вы уточнить, что я делаю, так это то, что я разделяю объекты DATE и TIME и верну их обратно, я ожидаю, что они будут такими же. –

+0

Что делает метод '.getTime()'? – Sionnach733

ответ

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, просто подведя итоги, одна из двух дельт потеряется, потому что один объект даты не может принимать во внимание два смещения.

Вывод: вы пытались совместить дату и время, суммируя их utc-longs, но это, как правило, ошибочный подход. Дата Плюс Дата Нет Дата, но не определено! В языке, специфичном для домена, вы можете добавлять только продолжительность/период к дате/времени.Таким образом, раствор, содержащий объект полуночи может быть:

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 
+0

Я использую это как I, когда я использую это: SimpleDateFormat sdfFull = new SimpleDateFormat ("yyyy-MM-dd HH: mm: ss"); И час тоже утерян. –

+0

Значит, вы говорите, потому что это разница между java.sql.Date/java.sql.Time час пропущен? –

+0

@KarlMorrison Вы также должны сделать 'sdfFull.setTimeZone (...)' перед тем, как применить его на своем j.u.Date-объекте (коснулась версии), иначе вы снова получите зависящий от часовой пояс результат, отличный от sql-вариантов. –

1

Я думаю, что я сделал ответ ма вопрос (помните timeObject в БД 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 
+0

Посмотрите мой новый анализ, почему ваш код не удался. –

+0

В противном случае ваш новый код, похоже, будет в порядке, поэтому мой upvote. –

+0

Ваш ответ был действительно тем, что я искал по оригинальному вопросу! следующий шаг пытался получить мой объект TIME 15:00:00 GMT + 0, чтобы перейти к 16:00:00 по GMT + 1. Теперь я понимаю это больше, чем данке! :) –

Смежные вопросы