我们在数据库中有一列update_date。 TIMESTAMP
类型的此Oracle数据库列已更新为ET时间。
当我处于UTC时间-19-Oct-2019 4:51 AM
时,DB将此时间保存在Update_date Column中作为19-Oct-19 00:51 AM
。
我尝试从数据库将Update_date转换为Java中的UTC。没用尽管如此,它仅显示ET时区。
我当前的系统时区是UTC-19-Oct-2019 4:51 AM
数据库保存ET时区-19-Oct-2019 00:51 AM
在Java中将数据库列(ET时区)转换为UTC:19-Oct-2019 00:51 AM
预期输出:19-Oct-2019 4:51 AM
使用Java代码不起作用:
Date fromDate = new Date(2019,10,19,00,51,00); //ET time from DB Update_date column
DateFormat gmtFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm aa");
TimeZone gmtTime = TimeZone.getTimeZone("GMT");
gmtFormat.setTimeZone(gmtTime);
System.out.println(gmtFormat.format(fromDate));
[Stack Overflow]已多次讨论此问题,所以我会简短地介绍。而且您忽略了提供重要的详细信息,例如什么数据库以及列的数据类型是什么,因此我无法给出具体的代码解决方案。
要检索数据库的瞬间,请使用OffsetDateTime
。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
[要查看特定地区(时区)的人们所使用的挂钟时间,请应用ZoneId
以获取ZonedDateTime
对象。
注意,“ ET时间”是不是一个时区。以proper time zone name的格式指定Continent/Region
,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们是not真实时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
对于类似于SQL-standard TIMESTAMP WITH TIME ZONE
的列,许多数据库在存储前会将输入调整为UTC。因此,在检索时,OffsetDateTime
对象可能位于UTC中。但可以肯定的是,只需提取一个OffsetDateTime
。根据定义,Instant
始终为UTC。
Instant
如果您的列属于类似于SQL标准Instant
的类型,则您使用错误的类型来跟踪时刻,即时间轴上的特定点。您不知道以前存储的值所在的时区是什么,因为任何提供的时区或偏移量信息都会被忽略并从所有输入中剥离。因此,您的手会一团糟。您必须Instant instant = odt.toInstant() ; // Adjust to UTC (if not already in UTC).
使用正确的类型。您可以尝试猜测预期的时区,并在重构期间应用该时区,但是您只能猜测。
TIMESTAMP WITHOUT TIME ZONE
完成后,删除旧列,或重命名以指示不再使用它。
您的refactor your database可能能够处理// Extract old value without zone/offset info.
LocalDateTime ldt = myResultSet.getObject( oldColumn , LocalDateTime.class ) ;
// Guessing this time zone was originally intended.
ZoneId z = ZoneId.of( "America/New_York" ) ;
// Arbitrarily apply the time zone that we assume, but do not truly know, was intended when that date-time was originally stored.
ZonedDateTime zdt = ldt.atZone( z ) ;
OffsetDateTime odt = zdt.toOffsetDateTime() ;
// Store the new value in a new column.
myPreparedStatement.setObject( newColumn , odt ) ;
。但是JDBC driver规范仅需要支持ZonedDateTime
。
ZonedDateTime