java - 为什么 java.time.ZoneId 没有实现 Comparable 接口?
问题描述
只是出于好奇,为什么我不能比较时区?
例如,一个时区可能是与 UTC 相关的 -2:00,而另一个时区可能是 +2:00。为什么不将它们视为 -2:00 < +2:00 等等?
解决方案
由于对Time ZonesZoneId
进行编码并且它改变了 UTC 的偏移量,因此没有order。
这就是为什么ZoneOffset
实现Comparable<ZoneOffset>
,因为它是一个固定的偏移量。
(补充说明)
例如:
Canada/Newfoundland -02:30/-03:30 ~ America/Belem -03:00/-03:00
有时的顺序Newfoundland ~ Belem
是,-02:30 > -03:00
但有时是-03:30 < -03:00
。
A < B
列出偏移顺序从 更改为 的所有(从现在到四年)区域 id 对的简单方法B < A
可能是:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class ZoneIdOrderChanges {
public static void main(String... args) {
// all zones
List<ZoneId> zonesId = ZoneId.getAvailableZoneIds().stream().map(ZoneId::of).collect(toList());
// all combinations two by two without repetition
final List<Tuple<ZoneId, ZoneId>> pairs = IntStream.range(1, zonesId.size()).boxed().flatMap(a ->
IntStream.range(a + 1, zonesId.size()).mapToObj(b ->
new Tuple<>(zonesId.get(a), zonesId.get(b)))).collect(toList());
// from now up to 4 years after now
OffsetDateTime t0 = OffsetDateTime.now();
OffsetDateTime t = OffsetDateTime.now();
OffsetDateTime sentry = t.plus(4, ChronoUnit.YEARS);
BiFunction<OffsetDateTime, Integer, Integer> compareZones = (d, i) ->
Integer.compare(ZonedDateTime.ofInstant(d.toInstant(), pairs.get(i).a).getOffset()
.compareTo(ZonedDateTime.ofInstant(d.toInstant(), pairs.get(i).b).getOffset()), 0);
Function<OffsetDateTime, int[]> forder = z -> IntStream
.range(0, pairs.size())
.map(i -> compareZones.apply(z, i))
.toArray();
int[] order = forder.apply(t);
Set<String> examples = new HashSet<>();
while (t.compareTo(sentry) <= 0) {
int[] o = forder.apply(t);
if (Arrays.compare(order, o) != 0) {
for (int i = 0; i < o.length; i++)
// only interested in not equals cases
if (order[i] != o[i] && order[i] != 0 && o[i] != 0) {
final OffsetDateTime tt = t;
String example = Stream.of(pairs.get(i).a, pairs.get(i).b)
.map(z -> String.format("%s %s/%s",
z.getId(),
ZonedDateTime.ofInstant(t0.toInstant(), z).getOffset(),
ZonedDateTime.ofInstant(tt.toInstant(), z).getOffset()))
.collect(joining(" ~ "));
if (!examples.contains(example)) {
examples.add(example);
System.out.println(example);
}
}
}
t = t.plus(1, ChronoUnit.DAYS);
}
}
@Getter
@Setter
@AllArgsConstructor
static class Tuple<A, B> {
private A a;
private B b;
}
}
带输出(针对该时间间隔和当前规则)
Asia/Yerevan +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Yerevan +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Etc/GMT-4 +04:00/+04:00 ~ Iran +04:30/+03:30
Etc/GMT-4 +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Dubai +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Dubai +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Reunion +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Reunion +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Mauritius +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Mauritius +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Saratov +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Saratov +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Samara +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Samara +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Mahe +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Mahe +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Baku +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Baku +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Muscat +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Muscat +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Volgograd +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Volgograd +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Iran +04:30/+03:30 ~ Europe/Astrakhan +04:00/+04:00
Iran +04:30/+03:30 ~ Asia/Tbilisi +04:00/+04:00
Iran +04:30/+03:30 ~ Europe/Ulyanovsk +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Europe/Astrakhan +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Asia/Tbilisi +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Europe/Ulyanovsk +04:00/+04:00
Pacific/Fakaofo +13:00/+13:00 ~ NZ-CHAT +12:45/+13:45
Pacific/Fakaofo +13:00/+13:00 ~ Pacific/Chatham +12:45/+13:45
NZ-CHAT +12:45/+13:45 ~ Pacific/Enderbury +13:00/+13:00
NZ-CHAT +12:45/+13:45 ~ Pacific/Tongatapu +13:00/+13:00
NZ-CHAT +12:45/+13:45 ~ Etc/GMT-13 +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Pacific/Enderbury +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Pacific/Tongatapu +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Etc/GMT-13 +13:00/+13:00
Pacific/Yap +10:00/+10:00 ~ Australia/Yancowinna +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/Adelaide +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Yancowinna +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Adelaide +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Chuuk +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Queensland +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Chuuk +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Queensland +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Pacific/Chuuk +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Chuuk +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Queensland +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Australia/Queensland +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Pacific/Guam +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Truk +10:00/+10:00 ~ Australia/South +09:30/+10:30
Asia/Vladivostok +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Saipan +10:00/+10:00 ~ Australia/South +09:30/+10:30
Antarctica/DumontDUrville +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/South +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/South +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/South +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/South +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Etc/GMT-1 +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Tunis +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Malabo +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
America/Godthab -02:00/-03:00 ~ America/St_Johns -02:30/-02:30
America/Godthab -02:00/-03:00 ~ Canada/Newfoundland -02:30/-02:30
Africa/Lagos +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Algiers +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Ndjamena +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Antarctica/Troll +02:00/Z ~ Africa/Libreville +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/El_Aaiun +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Douala +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Brazzaville +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Porto-Novo +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Casablanca +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Luanda +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Kinshasa +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Bangui +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Niamey +01:00/+01:00
America/Asuncion -04:00/-03:00 ~ SystemV/AST4ADT -03:00/-04:00
Chile/Continental -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Chile/Continental -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Catamarca -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Catamarca -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Canada/Atlantic -03:00/-04:00 ~ America/Asuncion -04:00/-03:00
America/Argentina/Cordoba -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Cordoba -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Araguaina -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Araguaina -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Salta -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Salta -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Etc/GMT+3 -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Etc/GMT+3 -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Montevideo -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Montevideo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Brazil/East -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Brazil/East -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Mendoza -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Mendoza -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Rio_Gallegos -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Rio_Gallegos -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Catamarca -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Catamarca -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Cordoba -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Cordoba -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/St_Johns -02:30/-03:30 ~ America/Sao_Paulo -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Jujuy -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Cayenne -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Recife -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Buenos_Aires -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Paramaribo -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Mendoza -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Santarem -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Asuncion -04:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Maceio -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Atlantic/Stanley -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Antarctica/Rothera -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/San_Luis -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Santiago -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Ushuaia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Antarctica/Palmer -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Punta_Arenas -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Fortaleza -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/La_Rioja -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Belem -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Jujuy -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Bahia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/San_Juan -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/ComodRivadavia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Tucuman -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Rosario -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Buenos_Aires -03:00/-03:00
America/Sao_Paulo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Jujuy -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Cayenne -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Recife -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Buenos_Aires -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Paramaribo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Moncton -03:00/-04:00 ~ America/Asuncion -04:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Mendoza -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Santarem -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Asuncion -04:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Maceio -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Atlantic/Stanley -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Antarctica/Rothera -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/San_Luis -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Santiago -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Ushuaia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Antarctica/Palmer -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Punta_Arenas -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Fortaleza -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/La_Rioja -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Belem -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Jujuy -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Bahia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/San_Juan -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/ComodRivadavia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Tucuman -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Rosario -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Buenos_Aires -03:00/-03:00
America/Asuncion -04:00/-03:00 ~ Atlantic/Bermuda -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Halifax -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Glace_Bay -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Thule -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Goose_Bay -03:00/-04:00
America/Atka -09:00/-10:00 ~ Pacific/Marquesas -09:30/-09:30
Pacific/Marquesas -09:30/-09:30 ~ America/Adak -09:00/-10:00
Pacific/Marquesas -09:30/-09:30 ~ US/Aleutian -09:00/-10:00
推荐阅读
- python - 为什么在mongoengine中更新ListField会这么慢?
- django - 我的创建视图既不保存对象也不重定向到下一页?
- php - 从 C++ 中的 PHP 扩展获取函数参数值
- azure - Azure IAAS、PaaS 和 SaaS 服务产品列表
- c# - 如何使用函数弹出堆栈中的所有元素
- google-cloud-platform - 从 GCP 计算实例复制到存储桶时出现 AccessDeniendException
- node.js - k8s 中的 grpc 无法解析服务 dns 名称
- javascript - 如何在do-while循环中使用承诺等待回调完成
- dependency-injection - 如何在 Autofac ContainerBuilder 中为每个 IService 注册一个 ServiceHelper?
- sql-server - 从 2 张桌子算起