如何根据给定UTC时间与目标时区小时数查找对应ZoneId
查询符合指定当前小时数要求的ZoneId最优方案
核心逻辑
最优方案可以通过三步实现,性能和准确率都有保障:
- 先获取当前UTC时间的小时数,记为
utcHour - 计算目标小时数与
utcHour的差值,得到需要的UTC偏移小时数:targetOffsetHour = 目标小时数 - utcHour - 遍历所有可用ZoneId,基于当前时间计算每个ZoneId的实际偏移量,筛选出和目标偏移量匹配的条目即可
示例演示
假设当前UTC时间为2021-10-22T11:40:37.808Z,需要找到所有当前小时数为17的ZoneId:
- 提取当前UTC小时数为11
- 计算目标偏移量:
17 - 11 = 6,即需要匹配UTC偏移为UTC+06:00的时区 - 筛选后符合要求的ZoneId包括
Asia/Kashgar、Asia/Almaty等,其中Asia/Kashgar的固定偏移就是UTC+06:00,完全符合条件
实现注意点
- 不要直接用固定偏移量映射时区,部分时区存在夏令时调整,同一ZoneId在不同时段的偏移量可能发生变化,必须基于当前时间计算实际偏移量再筛选,避免出现误差
- Java 8及以上版本可以直接使用内置
java.time包实现,无需引入第三方依赖
代码示例(Java 8+)
import java.time.Instant; import java.time.ZoneId; import java.time.ZoneOffset; import java.util.List; import java.util.stream.Collectors; public class ZoneIdQueryDemo { public static List<ZoneId> getMatchedZoneIds(int targetHour) { Instant currentUtcTime = Instant.now(); // 获取当前UTC小时数 int utcHour = currentUtcTime.atZone(ZoneOffset.UTC).getHour(); ZoneOffset targetOffset = ZoneOffset.ofHours(targetHour - utcHour); // 筛选符合偏移要求的时区 return ZoneId.getAvailableZoneIds().stream() .map(ZoneId::of) .filter(zoneId -> zoneId.getRules().getOffset(currentUtcTime).equals(targetOffset)) .collect(Collectors.toList()); } public static void main(String[] args) { // 示例:查询当前小时数为17的所有ZoneId List<ZoneId> matchedZones = getMatchedZoneIds(17); matchedZones.forEach(System.out::println); } }
内容的提问来源于stack exchange,提问作者Artur
相关产品推荐
相关产品推荐

