Reputation: 903
I have some code to get the difference between two time zone offsets of two dates.
int diff= date1.getTimezoneOffset() - date2.getTimezoneOffset();
but i'm using the method getTimezoneOffset()
, this method are deprecated and I need to do the same with other ways.
How I get the timezone offset between two dates?
PS.: I don't know what is the TimeZone of this dates.
Upvotes: 1
Views: 1049
Reputation: 338604
This Question is surprisingly tricky.
The java.util.Date
class was designed originally to have a time zone. The JVM’s current default time zone is implicitly assigned with the no-arg constructor. We can extract the offset of that timezone via the getTimeZoneOffset
command, as seen in this example.
java.util.Date date = new java.util.Date();
int offset = date.getTimezoneOffset ();
Result for me in my America/Los_Angeles
time zone:
420
Divide by 60 to get 7, as in the 7 hours behind UTC that is west coast US Daylight Saving Time (DST). Note how this class uses a positive number rather than the negative number for offsets behind UTC used more commonly such as in ISO 8601.
So if you really want to get the difference in offsets of two java.util.Date objects, subtract the pair of int
values returned by getTimeZoneOffset
for minutes, and divide by 60 for hours. Tip: Not all time zones are whole hours. For example, India is five and a half hours ahead of UTC, +05:30
.
You can see the time zone used by this class’ implementation of the toString
method.
System.out.println ( "now: " + new java.util.Date ().toString () );
Tue Oct 27 18:49:45 PDT 2015
By the way, note the use of PDT
in that string. Such 3-4 letter codes are neither standardized nor unique, and should be avoided. Yet another of many problems with this class. Instead use proper time zone names such as America/Los_Angeles
or Africa/Casablanca
.
Oddly, there is no constructor in which you can specify the time zone. Nor is there a setter method for setting the time zone. I am considering both deprecated and current methods. As an alternative, you might think you could pass an offset as part of the input string passed to either the constructor on the static Date.parse
method. But no, both of those return a long (number of seconds since the epoch) rather than a j.u.Date assigned that passed offset. This is why we often say as shorthand that "a java.util.Date has no time zone" which is not technically correct yet is apt in a practical sense.
.Calendar
In Java 1.1 the java.util.Calendar
class was added to take over the tracking of the time zone and other matters. So the java.util.Date class is left with its vestigial time zone internally assigned, not quite explicit yet not quite dormant.
All of this is a big confusing mess. The sane way out is to avoid the old date-time classes altogether:
…and their relatives.
The old classes are now supplanted by the new java.time framework built into Java 8 and later. Inspired by the highly successful Joda-Time library, defined by JSR 310, and extended by the ThreeTen-Extra project. See the Tutorial.
There is some learning curve to get the hang of this framework, but it is time well spent. The new classes are logical, uniform, and extremely useful. Convenience methods provide for converting to the old types when interoperating with code not yet updated to handle the new types.
The Instant
class is a moment on the timeline in UTC. A ZonedDateTime
is an Instant adjusted into a time zone represented as a ZoneId
.
Instant instant = Instant.now();
ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Dump to console.
System.out.println ( "instant: " + instant + " | zoneId: " + zoneId + " | zdt: " + zdt );
instant: 2015-10-28T02:25:25.719Z | zoneId: America/Los_Angeles | zdt: 2015-10-27T19:25:25.719-07:00[America/Los_Angeles]
Keep in mind that a time zone is an offset-from-UTC plus a set of rules for handling past, present, and future anomalies such as Daylight Saving Time. A ZoneId
is a time zone, while ZoneOffset
is just the offset-from-UTC without all the other rules. Once we have the ZoneOffset
in hand, we can ask about the offset as a number of seconds.
ZoneOffset zoneOffset = zdt.getOffset ();
int offsetAsSeconds = zoneOffset.getTotalSeconds ();
Dump to console.
System.out.println ( "zoneOffset: " + zoneOffset + " = offsetAsSeconds: " + offsetAsSeconds );
zoneOffset: -07:00 = offsetAsSeconds: -25200
You could compare a pair of ZonedDateTime
objects to get their respective offset as seconds, then subtract to get their difference.
Upvotes: 1