Convert java.sql.Timestamp to java.sql.Timestamp in another timezone

sankethm7 picture sankethm7 · Jun 25, 2012 · Viewed 13.2k times · Source

I am in need to manipulate on java.sql.Timestamp.

Input to the function is: Formatted DateTime in java.sql.Timestamp [Possible date formats are: MM/dd/yyyy hh:mm:ss aa, MM/dd/yyyy hh:mm:ss, MM/dd/yyyy hh:mm aa, MM/dd/yyyy HH:mm, MM/dd/yy hh:mm aa, MM/dd/yy HH:mm, MM/dd/yyyy, and some others]

Required Output: java.sql.Timestamp in another Timezone the same formatted DateTime as input

So basically I need to change timezone of the DateTime in java.sql.Timestamp

I have seen other posts, which mention to use JODA, but I can't use it due to some restrictions.

I have tried - to convert java.sql.Timestamp to java.date.Calendar, - then change the timezone, - then convert to it to date - format date to the same formatted datetime

See the code below:

Timestamp ts = "2012-06-20 18:22:42.0";  // I get this type of value from another function
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
cal.add(Calendar.HOUR, -8);
String string = cal.getTime().toString();     // return value is in " DAY MMM dd hh:mm:ss PDT yyyy " format i.e. Wed Jun 20 10:22:42 PDT 2012
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");  // This could be any format required
Date date;
try {
   date = formatter.parse(string);             // I am getting exception here on parsing 
} catch (ParseException e1) {
   e1.printStackTrace();
}

Can anyone tell me what is wrong here, or is there any other way to manipulate on Timezone for java.sql.Timestamp ?

Thanks.

Answer

Basil Bourque picture Basil Bourque · Apr 6, 2018

You are misunderstanding and abusing these classes.

Timestamp & Date have no time zone but UTC

manipulate on Timezone for java.sql.Timestamp

A java.sql.Timestamp is always a moment in UTC. No other time zone is involved, only UTC. Ditto for java.util.Date – always in UTC, no other time zone involved.

So your Question, as quoted above, does not make sense.

Timestamp & Date have no “format”

Neither Timestamp nor Date have a “format”. They use their own internally defined way to track the date-time. They are not strings, so they have no format. You can generate a String to represent their value in a particular format, but such a String is distinct and separate from the generating object.

java.time

You are using troublesome old date-time classes that wore supplanted years ago by the java.time classes.

Both Timestamp and Date are replaced by Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Your input is

String input = "2012-06-20 18:22:42.0" ;

That input is nearly compliant with standard ISO 8601 format. To comply fully, replace the SPACE in the middle with a T.

String input = "2012-06-20 18:22:42.0".replace( " " , "T" ) ;

Parse as a LocalDateTime because it lacks an indicator of offset-from-UTC or time zone.

LocalDateTime ldt = LocalDateTime.parse( input ) ;

A LocalDateTime, like your input string, does not represent a moment, is not a point on the timeline. Without the context of a time zone or offset-from-UTC, it has no real meaning. It represents only potential moments along a range of about 26-27 hours.

If you know the intended time zone, apply it to get a ZonedDateTime object.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

As for the other formats you mentioned, your Question is not at all clear. Search Stack Overflow for DateTimeFormatter class to see many examples and discussions of generating/parsing strings with the java.time classes. But first, get clear on the crucial concept that strings are not the date-time objects, and the date-time objects are not strings.

Database

If you were using java.sql.Timestamp to exchange data with a database, no need for that class anymore. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.

myPreparedStatement.setObject( … , instant ) ;

…and…

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

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.