How to Compare TimeZones

I need to compare time zones to Asia/Singapore <<t21 < Pacific/Honolulu .

I work with java.util.TimeZone (which does not implement Comparable ).

My search for an existing implementation was unsuccessful due to the overwhelming number of questions about comparing dates with different time zones.

Question: What is the correct implementation of Comparator<TimeZone> that will solve this problem (and what makes it better than other solutions, if applicable)?

Please note that I cannot use Joda Time for this problem, so "use Joda Time" is not a valid answer.

Edit for clarity.

The designation < above has not been clearly defined. In my particular use case, only a naive "geographic" order from east to west is required. As noted in the comments, a more advanced and generalized solution will take into account time factors, such as daylight saving time and historical GMT offset changes. Therefore, I think that we can consider two orders, each of which requires a different implementation of Comparator<TimeZone> :

  • Strictly geographical (current UTC) - the address is my answer .
  • Sensitive to local or civil time changes - refer to rgettman's answer .
+6
source share
3 answers

You can create a Comparator<TimeZone> that takes into account time zone differences. TimeZone may or may not guarantee daylight saving time, which adjusts the raw offset, thereby mixing comparisons only with the original offset. The TimeZone class seems to support customization based on getOffset methods 2, but they need a key date. What about:

 public class TimeZoneComparator implements Comparator<TimeZone> { private long date; public TimeZoneComparator(long date) { this.date = date; } public int compare(TimeZone tz1, TimeZone tz2) { return tz2.getOffset(this.date) - tz2.getOffset(this.date); } } 
+3
source

I performed my own implementation of Comparator<TimeZone> using getRawOffset for comparison:

 @Override public int compare(TimeZone tz1, TimeZone tz2) { return tz2.getRawOffset() - tz1.getRawOffset(); } 

He seems to have passed a quick test:

 final List<TimeZone> timeZones = Arrays.asList( TimeZone.getTimeZone("UTC"), TimeZone.getTimeZone("America/Los_Angeles"), TimeZone.getTimeZone("America/New_York"), TimeZone.getTimeZone("Pacific/Honolulu"), TimeZone.getTimeZone("Asia/Singapore") ); final List<TimeZone> expectedOrder = Arrays.asList( TimeZone.getTimeZone("Asia/Singapore"), TimeZone.getTimeZone("UTC"), TimeZone.getTimeZone("America/New_York"), TimeZone.getTimeZone("America/Los_Angeles"), TimeZone.getTimeZone("Pacific/Honolulu") ); Collections.sort(timeZones, new Comparator<TimeZone>() { @Override public int compare(TimeZone tz1, TimeZone tz2) { return tz2.getRawOffset() - tz1.getRawOffset(); } }); //Impl note: see AbstractList.equals System.out.println(timeZones.equals(expectedOrder)); //true 

But I'm still wondering if there are pitfalls for this solution and / or if something is preferable.

+4
source

Time intervals are purely political, so any use that does not meet the requirements will cause user problems for users, depending on what the application does and who needs it or uses it. You will be better off asking a question explaining why you need it. There are contiguous time intervals in which one uses DST and the other does not. Thus, 60% of the year, TZ1 == TZ2, the other 40% TZ1 <TZ2. Or be that as it may.

There are geographical (lat long) time zone data and websites for requesting the time zone. Even the current DST settings. Therefore, you may need to install a dataset that needs to be updated at least once a year. Or web access.

You probably shouldn't assign them a value. Only geographical order - in longitude.

At first, if you could tell us what you are trying to do, it will be great. And the answer is different: strict a> b> c order based on local time. I coded the calendars for a while, so I really knew that. What is believed to require such orders?

+1
source

All Articles