使用timezone将数据库日期时间转换为java.util.Date转换

时间:2012-07-30 17:53:39

标签: java hibernate date jdbc timezone

我的任务是将存储在我的某个DB(Sql Server)表格列上的时间转换为指定的时区。该列始终包含UTC时区的时间。

我面临的问题是,当hibernate READS 列并将其设置为我的实体类时,它会在应用服务器的时区中设置时间。

对于Eg: 如果DB具有值 - 07 Jul 2012 10:30(实际上是UTC),则hibernate将映射的日期字段设置为07 Jul 2012 10:30 PST(假设JVM在PST运行)。

现在如果这个日期被转换为任何其他时区..比如GMT + 5:30,我会得到意想不到的结果

要解决上述问题......我编写了以下代码

 //Reading the DB time (which does not have timezone info)
 Date dbDate = entityObj.getDBUtcDate();

 //Setting GMT timezone to the date, without modifying the date
 Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
 c.set(dbDate.getYear(), dbDate.getMonth(), dbDate.getDate()..., dbDate.getMinutes());

 Date utcDate = c.getTime();

使用上面的代码..我可以将数据库存储在 UTC 时区的日期,但当我转换到其他时区时(比如GMT + 5:30)使用以下逻辑

Calendar outCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+5:30"));
outCal.setTimeInMillis(utcDate.getTime());

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, outCal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, outCal.get(Calendar.MONTH));
cal.set(Calendar.DAY_OF_MONTH, outCal.get(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, outCal.get(Calendar.HOUR_OF_DAY));                                              
cal.set(Calendar.MINUTE, outCal.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, outCal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, outCal.get(Calendar.MILLISECOND));

//Converted date
Date pstTime = cal.getTime();
//Converted time mill seconds
long timeMilSec = pstTime.getTime();

转换日期的时间毫秒开始为负数(-54672 ...),这似乎代表无效时间。

我的问题是 如何从DB恢复时区信息(不必在DB中有任何额外的列来专门存储时区信息)?

OR

如何将数据库时间转换为具有指定时区(UTC)的时间?

PS:我希望以java.util.Date / Calendar的形式输出,因为我需要在这个日期再做一次转换

请帮我解决这个问题

1 个答案:

答案 0 :(得分:5)

Java中的日期没有时区。它们只是一个普遍的瞬间。如果要在给定时区中显示日期,则只需使用使用此时区初始化的DateFormat:

DateFormat df = DateFormat.getInstance();
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("The date in the database, in the UTC time zone, is " 
                   + df.format(date));

您无需转换任何内容。日期格式根据格式化的通用即时消息和您告诉它使用的时区打印适当的值。

同样,如果您想知道日期是星期一还是星期二,或者是1点钟还是2点钟,您需要先选择一个时区,将其转换为日历,然后询问日历信息:

Calendar cal = Calendar.getInstance(someTimeZone);
cal.setTime(date);
System.out.println("The day for the date stored in the database, for the time zone "
                   + someTimeZone
                   + " is " + cal.get(Calendar.DATE));

附注:不要使用弃用的方法。他们因为充分的理由而被弃用。