我在使用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不要转换从数据库中读取的时间戳?
答案 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:ss
或M/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,这在大多数情况下已被弃用。日历也有时区,因此您可能会遇到类似的问题。