Java - 日期保存为前一天

时间:2012-11-07 09:34:32

标签: java postgresql gwt date glassfish

在数据库中保存日期时,我遇到了一种非常奇怪的行为。在我的(Linux centOS 6.2)服务器上,我使用glassfish应用服务器(3.1.1 - build 12)和Java(1.7.0_09),该应用程序是用Java + GWT开发的,它使用PostgreSQL服务器(9.2.1)。在应用程序内部,有几个日期字段保存在数据库中。日期字段使用datepicker(http://code.google.com/p/gwt-datepicker,r30)。

db关系的date属性是日期类型(不是时间戳)。有些日期在前一天保存在数据库中。问题仅发生在间隔之间的日期,例如1968年3月31日至1968年10月27日之间,这让我想起了某种夏季问题。但是,由于1969年没有发生这种情况,我无法很好地孤立这个问题。我正在尝试找到问题发生的其他日期间隔。 例如,如果我在应用程序中选择19.05.1968,则在保存到数据库后,日期将保存为18.05.1968。

奇怪的是,我在另一台服务器上有相同应用程序的另一个等级,并且在相同日期它们被正确保存。 这让我觉得问题可能依赖于:

  • glassfish配置;
  • java(java.util.Date implementation?);
  • 我缺少某种服务器配置

我尝试将我的服务器的每个配置设置为欧洲/罗马(我的时区),但没有。任何的想法?我怎么能解决或调查这个问题?

更新 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);

3 个答案:

答案 0 :(得分:6)

只需将日期的时间设置为12:00(而不是默认的0:00),您应该没问题。问题是GWT时区库不包括1990年之前的所有闰年,因此您将在服务器上得到错误的时间(因为该值以时间戳的形式发送并且是一小时关闭)。 / p>

顺便说一下:GWT有一个内置的日期选择器,请参阅http://gwt.google.com/samples/Showcase/Showcase.html#!CwDatePicker的演示

答案 1 :(得分:0)

您使用的是java.util.date还是java.sql。日期(后者是正确的)?我有一个与SQL Server类似的问题,即使它是常规的,是的,与夏季相关。

基本上,您将Java日期存储为特定日期的午夜。如果是夏季,日期会在23:00之前移动到前一天,然后时间会被截断!如果您使用“随机”时间戳发送日期,那么您将在夏季的24次中遇到问题。

我不记得确切的解决方案(它不会直接帮助你,因为它引用了不同的DBMS)但是在dB中有一个设置说“在收到它时存储日期”。您可以通过将dbcolumn更改为时间戳并查看时间的存储方式来测试是否是这种情况。

我做了一些研究 - 似乎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/是报告它的正确位置

答案 2 :(得分:0)

为出生日期实时面对此问题。

我做了以下修复,因此不会在上午12点保存日期,而是在服务器营业时间之前的早上6点保存日期。即使扣除一小时,也不会影响dob。

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

麦克答案很好。但是,如果我们在下午12点保存,如果用户在下午12点之前的营业时间输入日期,则日期比较可能会出错。