按当前时间在此区域中查找 ZoneId

Find ZoneId by current time in this zone

按此 ZoneId 到 UTC 时间的预期时间查找 ZoneId 的最佳方法是什么?

例如,

UTC 时间:
2021-10-22T11:40:37.808Z

需要找到任何 ZoneId,ZoneId 中的当前时间为:
17

17-11 = 6
所以我们正在寻找任何 ZoneId,它具有:
UTC+06:00

例如:
Asia/Kashgar (UTC+06:00)

可以得到所有的ZoneId和对应的偏移量

import java.time.*;
import java.util.*;

class Main {  
  public static void main(String args[]) { 
    System.out.println(zoneIdToOffsetMap()); 
  }

private static Map<String, String> zoneIdToOffsetMap() {
        Map<String, String> result = new HashMap<>();

        LocalDateTime localDateTime = LocalDateTime.now();

        for (String zoneId : ZoneId.getAvailableZoneIds()) {
            ZoneId id = ZoneId.of(zoneId);
            // LocalDateTime -> ZonedDateTime
            ZonedDateTime zonedDateTime = localDateTime.atZone(id);
            // ZonedDateTime -> ZoneOffset
            ZoneOffset zoneOffset = zonedDateTime.getOffset();
            //replace Z to +00:00
            String offset = zoneOffset.getId().replaceAll("Z", "+00:00");

            result.put(id.toString(), offset);
        }

        return result;
    }
}

这会打印出如下地图:

{Asia/Aden=+03:00, America/Cuiaba=-04:00, ...}

如果你真的想要给定偏移量的所有 ZoneIds,你可以将上面的代码稍微更改为 return String -> List<String> 的映射或只是 List<String> 对于单个偏移量,如下所示。

private static List<String> getZoneIds(String target) {
        List<String> zoneIds = new ArrayList<>();

        LocalDateTime localDateTime = LocalDateTime.now();

        for (String zoneId : ZoneId.getAvailableZoneIds()) {
            ZoneId id = ZoneId.of(zoneId);
            // LocalDateTime -> ZonedDateTime
            ZonedDateTime zonedDateTime = localDateTime.atZone(id);
            // ZonedDateTime -> ZoneOffset
            ZoneOffset zoneOffset = zonedDateTime.getOffset();
            //replace Z to +00:00
            String offset = zoneOffset.getId().replaceAll("Z", "+00:00");

            if (offset.equals(target)) {
                zoneIds.add(id.toString());
            }
        }

        return zoneIds;
    }
}

这会打印:

[Asia/Kashgar, Etc/GMT-6, Asia/Almaty, Asia/Dacca, Asia/Omsk, Asia/Dhaka, Indian/Chagos, Asia/Qostanay, Asia/Bishkek, Antarctica/Vostok, Asia/Urumqi, Asia/Thimbu, Asia/Thimphu]

你说:

So we are looking for any ZoneId, which has: UTC+06:00

时区使用的与 UTC 的偏移量随时间变化。这就是时区的定义:过去、现在和未来的历史变化,由特定地区的人民使用的偏移量由他们的政治家决定。

所以我们必须指定一个时刻,一个Instant,我们想知道当前的偏移量。

在下面的这段代码中,我们使用流来考虑所有时区中的每一个。对于每个时区,我们获取其规则集,即要偏移的更改历史记录。我们查询这些规则以了解在我们选择的时刻使用的偏移量。对于返回的偏移量,我们比较一下是不是我们想要的偏移量。

Instant instant = Instant.now() ;
ZoneOffset targetOffset = ZoneOffset.ofHours( 6 ) ;
List< ZoneId > zonesUsingDesiredOffset = 
    ZoneId
    .getAvailableZoneIds()  // Returns a `Set` of `String` objects, the names of each known time zone.
    .stream()
    .map( zoneName -> ZoneId.of( zoneName ) )  // Map each zone name to `ZoneId` object.
    .filter(
        zoneId -> zoneId.getRules().getOffset( instant ).equals( targetOffset )  // Filter for zones whose offset at specified moment matches our desired offset.
    )
    .collect( Collectors.toList() )
;

看到这个 code run live at IdeOne.com

[Asia/Kashgar, Etc/GMT-6, Asia/Almaty, Asia/Dacca, Asia/Omsk, Asia/Dhaka, Indian/Chagos, Asia/Qyzylorda, Asia/Bishkek, Antarctica/Vostok, Asia/Urumqi, Asia/Thimbu, Asia/Thimphu]