简体   繁体   中英

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.

PS: 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?

First of all Date class is part of the old outdated (no pun intended) infrastructure. If it is at all possible get rid of it and just use java.time package. But if you must work with Date then your problem with time zone is not a problem. your line System.out.println(gmtDate); only prints it with your local time zone, since the system assumes that it is the best option. But regardless of that Date holds a particular moment in time in milliseconds since January 1, 1970, 00:00:00 GMT. Class Date has methods compareTo() , after() and before() that allow you to compare 2 Dates. Also Date has method getTime() that returns you the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this date. So you can compare the long values. But again, The best option is to switch to java.time package and classes Instant and ZonedDateTime (and others) have methods compareTo(), isAfter() and isBefore().

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

You misunderstand the semantics of date time classes. java.util.Date is a specific point in time, an instant, it has no time zone associated with it. However if you have a time zone you can ask the time zone for the time of that java.util.Date .

java.sql.TimeStamp is the equivalent of java.time.LocalDateTime . It is not an instant and has no time zone associated with it.

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