Search code examples
javajava-8zoneddatetimesql-timestamp

For a given Date object, capture it's value relevant to GMT timezone


In my application running on Java 8, I have a Date object. The timezone for this object depends on the client's location.

At one particular point, I need to convert this Date to GMT so that it could be comparable to a value that I access from the DB.

I tried SimpleDateFormat and ZonedDateTime, but there's a pain-point. These API's provide me GMT time in String values, which is perfectly fine. However, once I parse it and assign it to a Date object, it is back to my local timezone!

For Ex:

public class TimeZoneDemo {
    public static void main(String[] args) throws ParseException {
        Date istDate = Calendar.getInstance().getTime();

        ZonedDateTime gmtTime = istDate.toInstant().atZone(ZoneId.of("GMT"));
        System.out.println(gmtTime);

        Date gmtDate = Date.from(gmtTime.toInstant());
        System.out.println(gmtDate);
    }
}

In the code above, gmtTime displays the right value relevant to the GMT timezone, but gmtDate (the Date object) prints value in the local time zone.

P.S.: My ultimate goal is to have a the GMT value in a java.sql.TimeStamp object.

How could this be achieved?

UPDATE 1: After going through the comments & replies I understand that the Date object just holds a long value containing milliseconds. BUT, my expectation here is that when this line is executed:

Date gmtDate = Date.from(gmtTime.toInstant());

Whatever time the object gmtTime contains, I need to capture just that time in a TimeStamp or Date object. The motive is to then be able to make comparison with a value persisted in the database. I'm passing the date as parameter to my SQL query.

Can someone pls help me understand how can this be achieved?


Solution

  • java.time and JDBC 4.2

    The answer is in @BasilBourque’s comment: use OffsetDateTime.

        PreparedStatement yourPreparedStatement = yourDatabaseConnection.prepareStatement(
                "select smth from your_table where your_time_stamp_col < ?;");
        OffsetDateTime gmtTime = OffsetDateTime.now(ZoneOffset.UTC);
        yourPreparedStatement.setObject(1, gmtTime);
    

    This requires a JDBC 4.2 compliant JDBC driver, I think that about all of us are using that by now. Which is good because it allows us to bypass java.sql.Timestamp and the other date-time types in java.sql. They are all poorly designed and long outdated.

    As others have said, neither of the outdated classes Date and Timestamp have any time zone or offset from UTC/GMT.

    Some related questions