【问题标题】:JPA Date and Timezone confusionJPA 日期和时区混淆
【发布时间】:2012-06-01 20:18:55
【问题描述】:

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

我从一个 CSV 文件填充了我的数据库,将日期作为字符串(格式为:6/30/2009-23:59:56)。我使用以下代码片段将其转换为 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 实体,getDataTs() 返回一个 java.util.Date 对象。 字符串原来是"Tue Jun 30 23:59:56 BRT 2009&gt;&gt;&gt;1246417196000"

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

【问题讨论】:

    标签: date jpa timezone


    【解决方案1】:

    如上所述,日期和时间戳不考虑时区。看来这个问题是因为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()

    【讨论】:

      【解决方案2】:

      您的日期是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 来显示您的时间戳。

      【讨论】:

      • 嗨。谢谢回答。粘贴格式确实是错误的(谢谢!),但问题仍然存在。正如我试图澄清的那样,我没有使用 DateFormat 显示日期。我将其转换为时间戳,并在图表上使用它。
      • 刚刚在原问题中添加了一个例子。
      【解决方案3】:

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

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

      一般而言,Java 中应使用 Calendar 而不是 java.util.Date,后者在很大程度上已被弃用。日历也有一个时区,所以你可能会遇到类似的问题。

      【讨论】:

      • java.util.Date 没有 TimeZone。而且它远没有被弃用(不幸的是)。顺便说一句,时间戳扩展了 java.util.Date。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 2022-01-03
      • 2016-03-15
      • 1970-01-01
      相关资源
      最近更新 更多