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

san*_*hat 1 java timezone hibernate date jdbc

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

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

例如:如果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();
Run Code Online (Sandbox Code Playgroud)

使用上面的代码..我可以将数据库存储日期恢复为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();
Run Code Online (Sandbox Code Playgroud)

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

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

要么

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

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

请帮我解决这个问题

JB *_*zet 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));
Run Code Online (Sandbox Code Playgroud)

你不需要转换任何东西.日期格式根据格式化的通用即时消息和您告诉它使用的时区打印适当的值.

同样,如果您想知道日期是星期一还是星期二,或者是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));
Run Code Online (Sandbox Code Playgroud)

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