简体   繁体   中英

Selecting UTC date from Oracle and converting to UTC in Java

If I call in my app:

System.currentTimeMillis()

the result will be, let's say: 1536842771599, which is : GMT: Thursday, September 13, 2018 12:46:11.599 PM OR in my local : Thursday, September 13, 2018 3:46:11.599 PM GMT+03:00 DST

If I do the following select on the Oracle database installed locally:

select CAST(sys_extract_utc(SYSTIMESTAMP) AS DATE) from dual;

I get, through the following JdbcTemplate code:

jdbc.queryForObject(sqlCommand, new Object[0], Timestamp.class);

the following result: 在此处输入图片说明

Which in my opinion is already wrong because Timestamp usually represents localized time. Further, if I call:

myResult.getTime()

to get the long value, this will convert my time, which was around 12.46 PM, to the value 1536831971599, which is actually: GMT: Thursday, September 13, 2018 9:46:11.599 AM.

Obviously this is not good because it is 2 * GMT+03:00 (6 hours) behind my actual local time, and GMT+03:00 (3 hours) behind UTC time of the Database.

What I'm doing wrong? My only conclusion up until now is to avoid doing a sys_extract_utc on a database and let database return me local time which will be converted to UTC time when I will call getTime on the Timestamp instance.

Any explanation to this?

PS Base on the answer that java.sql.Timestamp is UTC, I attach a screenshot of what debugger shows to me, and which is wrong, because it considers the result which is UTC to be GMT+03:00. So, it shows my time as 8.26 + 03:00. My local time is 11.26. If I call getTime on this instance of Timestamp, I will get a long value which if I put into https://www.epochconverter.com/ then I get Friday, September 14, 2018 8:26:06 AM GMT+03:00 DST or Friday, September 14, 2018 5:26:06 AM which is exactly 3 hours behind of what I actually have as UTC!

PS2 I use Spring JDBC 4.2.5-RELEASE. Can't use Instant with it, it throws exception that cannot convert Timestamp to Instant because it expects something that derives from Number. I cannot change this JDBC, even version, now, unfortunately.

在此处输入图片说明

tl;dr

You misunderstand the java.sql.Timestamp class.

  • java.sql.Timestamp always represents a moment in UTC.
  • java.time.Instant years ago replaced Timestamp .

Use only Instant , never Timestamp .

Instant

The terrible java.sql.Timestamp class is now outmoded by the java.time classes, specifically Instant .

Instant.now()  // Capture the current moment in UTC. 

JDBC 4.2

As of JDBC 4.2, we can directly exchange java.time objects with the database. No need to ever again use the awful Date , Calendar , or java.sql classes.

Retrieve.

Instant instant = myResultSet.getObject( … , Instant.class ) ;

Insert.

myPreparedStatement.setObject( … , instant ) ;

Timestamp usually represents localized time.

Incorrect. A java.sql.Timestamp represents a moment in UTC, always UTC, by definition. Likewise, Instant too represents a moment in UTC. Both classes represent a count since the first moment of 1970 in UTC.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM