Подтвердить что ты не робот

Java - дата сохраняется как за день до

У меня очень странное поведение при сохранении дат в базе данных. На моем (Linux centOS 6.2) сервере я использую сервер приложений Glassfish (3.1.1 - build 12) и Java (1.7.0_09), приложение разработано в Java + GWT и использует сервер PostgreSQL (9.2.1). Внутри приложения есть несколько полей даты, которые сохраняются на db. В полях даты используется datepicker (http://code.google.com/p/gwt-datepicker, r30).

Атрибут date отношения db - это тип даты (не временная метка). Некоторые даты сохраняются за день до этого в базе данных. Проблема возникает только для дат между интервалами, например. между 31.03.1968 и 27.10.1968, что заставляет меня думать о какой-то проблеме летнего времени. Но, поскольку это не происходит в 1969 году, например, я не могу изолировать проблему очень хорошо. Я пытаюсь найти другой интервал дат, внутри которого возникает проблема. Например, если я выбираю 19.05.1968 в приложении, после сохранения в базе данных дата сохраняется как 18.05.1968.

Странно, что у меня есть другое значение одного и того же приложения на другом сервере, и для тех же дат они сохраняются правильно. Это заставляет меня думать, что проблема может положиться либо на:

  • конфигурация стеклянной рыбы;
  • java (реализация java.util.Date?);
  • какая-то конфигурация сервера отсутствует

Я попытался установить в Европу/Рим (мой часовой пояс) каждую конфигурацию моего сервера, но ничего. Есть идеи? Как я мог решить или исследовать эту проблему?

UPDATE: 1968 год был високосным. Проблема также возникает в 1972 году, которая снова високосный год. Подведение итогов: Проблема "с датой с сохранением одного дня раньше" происходит в високосные годы в течение интервала даты летнего времени.

Кодовая часть, в которой создается проект даты:

Date d = dateField.getSelectedDate();
if (d != null) {
    txtVal = DateTimeFormat.getFormat("dd/MM/yyyy").format(d);
}

где dateField объявляется как:

transient private DatePicker dateField;

Пакет org.zenika.widget.client.datePicker.DatePicker (ранее упоминавшийся gwt-datepicker-r30), а DateTimeFormat ссылается на com.google.gwt.i18n.shared.DateTimeFormat

ОБНОВЛЕНИЕ после принятия ответа:

Я использовал этот обходной путь: когда я создаю дату, я использую следующий код:

final long hours12 = 12L * 60L * 60L * 1000L;
Date d = new Date(d1.getTime() + hours12);
4b9b3361

Ответ 1

Просто установите время даты на 12:00 (вместо 0:00), и все будет в порядке. Проблема заключается в том, что библиотека часовых поясов GWT не включает все високосные годы с 1990 года, и, таким образом, вы получите неправильное время на сервере (поскольку значение отправляется в виде отметки времени и составляет один час).

Кстати: у GWT есть встроенный сборщик дат, см. его демо на http://gwt.google.com/samples/Showcase/Showcase.html#!CwDatePicker

Ответ 2

Используете ли вы java.util.date или java.sql. дата (последняя является правильной)? У меня была аналогичная проблема с SQL Server, даже если она была регулярной и да, связана с летним временем.

В принципе, вы храните дату Java как полночь определенного дня. если в летнее время, дата будет перенесена на день раньше в 23:00, а затем время будет усечено! Если вы отправите дату со случайной меткой времени, вы будете испытывать проблему один раз из 24 в течение лета.

Я точно не помню решение (которое не поможет вам напрямую, так как оно относится к другой СУБД), но в дБ была установлена ​​настройка "сохранить дату, когда вы ее получите". Вы можете проверить, если это так, изменив dbcolumn на timestamp и посмотрев, как время будет сохранено.

Я немного научился - похоже, у gwt-datepicker много проблем! http://code.google.com/p/google-apps-script-issues/issues/detail?id=2022 http://code.google.com/p/google-apps-script-issues/issues/detail?id= 2001

Я бы не удивился, если бы их расчеты имели ошибку в високосные годы. Кроме того, вполне возможно, что это просто несоответствие между тем, что вы делаете, и тем, что, по вашему мнению, вы делаете - работа с датами - это удивительно трудное дело.

Чтобы проверить, попробуйте:

final java.util.Date ud = dateField.getSelectedDate();;
final java.sql.Date sd = new java.sql.Date(ud.getTime());
System.out.println(ud);// this is what you pick from the DatePicker
System.out.println(sd);// this is what will be stored on the database

И посмотрите, совпадают ли они летом в високосные годы. Если это ошибка GWT, http://code.google.com/p/google-apps-script-issues/ - это правильное место, чтобы сообщить об этом

Ответ 3

Столкнувшись с этой проблемой в реальном времени на дату рождения.

Я сделал следующее исправление, так что вместо сохранения даты в 12 часов, дата будет сохранена в 6 утра, которая до рабочего времени сервера. Даже час вычитается, он не будет влиять на dob.

Calendar now = Calendar.getInstance();
now.setTime(YOUR_DATE);
now.set(Calendar.HOUR_OF_DAY, 6);
YOUR_DATE = now.getTime();

Ответ Майков в порядке. Но, если мы сохраним с 12 часов вечера, есть вероятность для сравнения ошибок в дате, если пользователь вводит дату в рабочее время до 12 часов.