I have to store UTC dateTime in DB.
I have converted the dateTime given in specific timezone to UTC. for that I followed the below code.
My input dateTime is "20121225 10:00:00 Z" timezone is "Asia/Calcutta"
My Server/DB(oracle) is running in the same timezone(IST) "Asia/Calcutta"
Get the Date object in this specific Timezone
String date = "20121225 10:00:00 Z";
String timeZoneId = "Asia/Calcutta";
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z");
//This date object is given time and given timezone
java.util.Date parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(false, TimeZone.SHORT));
if (timeZone.inDaylightTime(parsedDate)) {
// We need to re-parse because we don't know if the date
// is DST until it is parsed...
parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(true, TimeZone.SHORT));
}
//assigning to the java.sql.TimeStamp instace variable
obj.setTsSchedStartTime(new java.sql.Timestamp(parsedDate.getTime()));
Store into DB
if (tsSchedStartTime != null) {
stmt.setTimestamp(11, tsSchedStartTime);
} else {
stmt.setNull(11, java.sql.Types.DATE);
}
OUTPUT
DB (oracle) has stored the same given dateTime: "20121225 10:00:00
not in UTC.
I have confirmed from the below sql.
select to_char(sched_start_time, 'yyyy/mm/dd hh24:mi:ss') from myTable
My DB server also running on the same timezone "Asia/Calcutta"
It gives me the below appearances
Date.getTime()
is not in UTC- Or Timestamp is has timezone impact while storing into DB What am I doing wrong here?
One more question:
Will timeStamp.toString()
print in local timezone like java.util.date
does? Not UTC?
For Mysql, we have a limitation. In the driver Mysql doc, we have :
So, when we do not use this parameters and we call
setTimestamp or getTimestamp
with calendar or without calendar, we have the timestamp in the jvm timezone.Example :
The jvm timezone is GMT+2. In the database, we have a timestamp : 1461100256 = 19/04/16 21:10:56,000000000 GMT
The first method returns : 1461100256000 = 19/04/2016 - 21:10:56 GMT
The second method returns : 1461100256000 = 19/04/2016 - 21:10:56 GMT
The third method returns : 1461085856000 = 19/04/2016 - 17:10:56 GMT
Instead of Oracle, when we use the same calls, we have :
The first method returns : 1461093056000 = 19/04/2016 - 19:10:56 GMT
The second method returns : 1461100256000 = 19/04/2016 - 21:10:56 GMT
The third method returns : 1461085856000 = 19/04/2016 - 17:10:56 GMT
NB : It is not necessary to specify the parameters for Oracle.
I think the correct answer should be java.sql.Timestamp is NOT timezone specific. Timestamp is a composite of java.util.Date and a separate nanoseconds value. There is no timezone information in this class. Thus just as Date this class simply holds the number of milliseconds since January 1, 1970, 00:00:00 GMT + nanos.
In PreparedStatement.setTimestamp(int parameterIndex, Timestamp x, Calendar cal) Calendar is used by the driver to change the default timezone. But Timestamp still holds milliseconds in GMT.
API is unclear about how exactly JDBC driver is supposed to use Calendar. Providers seem to feel free about how to interpret it, e.g. last time I worked with MySQL 5.5 Calendar the driver simply ignored Calendar in both PreparedStatement.setTimestamp and ResultSet.getTimestamp.
It is specific from your driver. You need to supply a parameter in your Java program to tell it the time zone you want to use.
Further this:
May also be of value in handling the conversion properly. Taken from here
Although it is not explicitly specified for
setTimestamp(int parameterIndex, Timestamp x)
drivers have to follow the rules established by thesetTimestamp(int parameterIndex, Timestamp x, Calendar cal)
javadoc:When you call with
setTimestamp(int parameterIndex, Timestamp x)
the JDBC driver uses the time zone of the virtual machine to calculate the date and time of the timestamp in that time zone. This date and time is what is stored in the database, and if the database column does not store time zone information, then any information about the zone is lost (which means it is up to the application(s) using the database to use the same time zone consistently or come up with another scheme to discern timezone (ie store in a separate column).For example: Your local time zone is GMT+2. You store "2012-12-25 10:00:00 UTC". The actual value stored in the database is "2012-12-25 12:00:00". You retrieve it again: you get it back again as "2012-12-25 10:00:00 UTC" (but only if you retrieve it using
getTimestamp(..)
), but when another application accesses the database in time zone GMT+0, it will retrieve the timestamp as "2012-12-25 12:00:00 UTC".If you want to store it in a different timezone, then you need to use the
setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
with a Calendar instance in the required timezone. Just make sure you also use the equivalent getter with the same time zone when retrieving values (if you use aTIMESTAMP
without timezone information in your database).So, assuming you want to store the actual GMT timezone, you need to use:
With JDBC 4.2 a compliant driver should support
java.time.LocalDateTime
(andjava.time.LocalTime
) forTIMESTAMP
(andTIME
) throughget/set/updateObject
. Thejava.time.Local*
classes are without time zones, so no conversion needs to be applied (although that might open a new set of problems if your code did assume a specific time zone).