简体   繁体   中英

How to save timestamp with timezone

My Project support Postgres and SQLServer DB. I have a timestamp with a timezone column in my table x. When I save timestamp value in the DB. I'm getting as "2022-07-01 00:00:00.000000 +05:30" in the Postgres but in SQL server it is saving as "2022-07-01 00:00:00.000000 +00:00". Can someone help me on how to get the value as Postgres in SQL server also? Here is my java code

   DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
   Date parsedDate = dateFormat.parse("20220701T00:00:00") //this value comes as argument for this method. 
   return new Timestamp(parsedDate.getTime());

I'm getting as "2022-07-01 00:00:00.000000 +05:30" in the Postgres

No, you're not.

A TIMESTAMP WITH TIME ZONE column in Postgres stores its values “in UTC”, meaning an offset from UTC of zero hours-minutes-seconds. Any time zone or offset supplied with an input is used to adjust to UTC, then discarded.

Unfortunately, some tools and middleware have the anti-feature of applying a current default time zone to the retrieved value. pgAdmin is one such tool, I'm sad to report.

Another problem is that the toString method of java.util.Date also has the same anti-feature, applying the JVM's current default time zone.

Fortunately, the terrible Date class was supplanted years ago by the modern java.time classes defined in JSR 310. JDBC 4.2 and later requires support for java.time . No need to ever use Date , Calendar , and Timestamp .

To retrieve a value from a TIMESTAMP WITH TIME ZONE column:

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; 

👉 You'll see that object has an offset of zero, the true value stored in Postgres.

To write:

myPreparedStatement.setObject( … , odt ) ;

As for your input string, it lacks an indicator of time zone or offset. So parse as a LocalDateTime .

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HH:mm:ss" ) ;
String input = "20220701T00:00:00" ; 
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

Now assign the intended time zone or offset to get a ZonedDateTime or OffsetDateTime respectively. I'll assume you intend an offset of zero.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ; 

I suggest you educate the publisher of your data about proper use of standard ISO 8601 format.

Your input string is mixing the full format for the time-of-day portion with its COLON characters with the abbreviated “basic” format for the date portion.

I recommend sticking with the full expanded format.

2022-07-01T00:00:00

And if the publisher of that data intended an offset of zero, they should say so. Append a Z , pronounced Zulu . Or append +00:00 , though I'd recommend the Z .

2022-07-01T00:00:00Z


All this has been covered many times on Stack Overflow. Search to learn 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