Oracle's date and time without daylight savings via JDBC

梦想与她 提交于 2019-12-04 21:25:01

Simply put, selecting an oracle DATE into a Java Date is inherently problematic. That's because they are fundamentally different. An Oracle DATE is the combination of year, month, day, hours, minute, seconds, without any timezone information, so it could be any timezone, with or without daylight saving - Oracle doesn't know, since that information isn't included in the DATE.

On the other hand, a Java Date basically is the number of milliseconds since 1/1/1970 00:00:00 UTC.

When an Oracle DATE goes into a Java Date, the JDBC driver can only guess which timezone to apply. The results are rather unpredictable, especially when the data in the database use another timezone than the user.

Java Dates don't have timezones until you format them.

A java date is internally stored as a long - the number of milliseconds elapsed since Jan 1, 1970, midnight UTC.

Look at the java Date's time, along with it's reported time zone (however you format it), and you'll probably see that it is equivalent to the time in the database.

You most likely have a problem with formatting the date - using a timezone other than the one that you expect. I'm guessing that you are not specifying the time zone (using the default one) when formatting, or simply using Date's toString() method.

If you use the Calendar (calendar.setTime(date)), you can combine the 'epoch time' with a specific time zone, or if it works for you, use the default time zone. You can also query a Calendar for it's timezone, and if the default one is incorrect, then you will indeed need to investigate whether either the computer itself is set to the wrong timezone, or whether something is amiss with the java timezone database on that computer.

"Java Dates don't have timezones until you format them." Wrong, it is defined as UTC. The original answer by ammoQ is correct. Database Date columns don't have timezone, although it may be stored as milliseconds since midnight 1 Jan 1970, it isn't defined as UTC, it is any timezone you like (ie same local time regardless of timezone).

In particular, JDBC uses the JVM's default timezone when converting to java Date in UTC. So if the database stores 1/1/2014 02:00, and your JVM is "America/Chicago" then you get a java Date equivalent to 1/1/2014 02:00 CST. If your JVM is "America/New_York" then you get a java Date equivalent to 1/1/2014 02:00 EST. This is a very different moment in time, an hour (3600000 milliseconds) differnt, which happens to be equivalent to 1/1/2014 01:00 CST, not 02:00 CST.

However the biggest issue with using the JVM's timezone occurs every year during the "overlap hour" if that timezone honors Daylight Saving Time. The database will say 01:30 on the fall-back Sunday (in US timezones), but which 01:30 is it, the first in Daylight Time or the second after the switch back to Standard Time? The JDBC/JVM has to arbitrarily choose between these two moments in time. As I recall, I think most JVMs will always use Standard Time (the second 01:30). Although during the Spring jump to Daylight Saving Time, a time of 02:30 technically does not exist, but I think most JVMs will assume 03:30 after the spring-forward to Daylight time.

Try vm parameter

-Duser.timezone=GMT-2

or

-Duser.timezone=America/Sao_Paulo

Java has its own timezone settings and it may affect transfer of Date objects.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!