JPA日期和时区混淆

时间:2012-06-01 20:18:55

标签: date jpa timezone

我在使用JPA从数据库中读取日期时遇到问题。我正在使用EclipseLink和PostgreSQL

我已经从CSV文件填充了我的数据库,其中日期为字符串(格式为:6/30/2009-23:59:56)。我使用以下snipet将其转换为Date对象:

public static Date parseDate(String s){
    DateFormat formatter = new SimpleDateFormat("d/M/yyyy-k:m:s");
    try {
        return new Date( ((java.util.Date)formatter.parse(s)).getTime() );
    } catch (ParseException ex) {
        Logger.getLogger(Type.class.getName()).log(Level.SEVERE, null, ex);
        return null;
    }
}

日期已正确转换并按预期存储在数据库中。以下是我将Date对象映射到数据库的方法:

@Column(name="data_ts", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
private Date dataTs;

当我尝试从数据库中读取日期以在图表中使用它时,问题似乎发生(Highcharts)。具有上述相同时间戳的记录读作:

Mon Jun 06 23:59:56 BRT 2011,时间戳为1307415596000

请注意,它在巴西时间(+ 3h),因此时间戳(根据GMT计算)是3小时移位。绘制后,时间戳变为指向07/06/2011 02:59:56

以下是一个例子:

List<TimedataEnt> timeData = currentWellsite.getTimeData();
String debug = timeData.get(timeData.size()-1).getDataTs().toString() + ">>>" + timeData.get(timeData.size()-1).getDataTs().getTime();

其中 currentWellsite 是JPA Entity,getDataTs()返回java.util.Date对象。 字符串结果为"Tue Jun 30 23:59:56 BRT 2009>>>1246417196000"

如何告诉JPA不要转换从数据库中读取的时间戳?

3 个答案:

答案 0 :(得分:3)

如上所述,日期和时间戳没有时区考虑。似乎问题是由于Java认为它从数据库中读取的时间是当前的默认时区而引起的。

因此,如果数据库包含2011-04-04 14:00:00且我当前的时区为+3,则将其分配给java Date将生成2011-04-04 14:00:00 BRT time(+3),时间戳移动3小时(因为时间戳是从UTC计算的)。

通过获取计算的时间戳来解决问题:

long ts = myDate().getTime() + TimeZone.getDefault().getRawOffset();

重要的是要说getRawOffset()不考虑夏令时。为此,请使用getOffset()

答案 1 :(得分:1)

您的约会日期为6/30/2009-23:59:56。我读到2009年6月30日23:59:56。因此,解析它的格式应为M/d/yyyy-HH:mm:ssM/d/yyyy-kk:mm:ss(取决于您的小时数是从1到24还是从0到23)。但绝对不是d/M/yyyy-k:m:s:这个月就在白天之前。

此外,时间戳没有任何时区。这是一个普遍的时刻。只有当您显示其值时,时区才是重要的,因为您必须选择用于显示时间的时区。使用设置了适当时区的DateFormat来显示时间戳。

答案 2 :(得分:0)

您的问题似乎是您将时间戳(没有时区)存储到java.util.Date(具有时区偏移量)中。

如果您想控制时区的设置方式,请将Timestamp存储为java.sql.Timestamp,或使用您自己的@Converter。

一般情况下,应该在Java中使用Calendar而不是java.util.Date,这在大多数情况下已被弃用。日历也有时区,因此您可能会遇到类似的问题。