java.time.DateTimeException:基于区域的ZoneId的ID无效,格式无效:java

java.time.DateTimeException:基于区域的ZoneId的ID无效,格式无效:java,java,time,timezone,Java,Time,Timezone,我想通过城市UTC和GMT时间,不加下划线。首先,我写这封信是为了获取区域ID: List<String> utc = new ArrayList<>(ZoneId.getAvailableZoneIds()); List<String> gmt = new ArrayList<>(ZoneId.getAvailableZoneIds()); 最后,我得到一个错误: java.time.DateTimeException: Invalid I

我想通过城市UTC和GMT时间,不加下划线。首先,我写这封信是为了获取区域ID:

 List<String> utc = new ArrayList<>(ZoneId.getAvailableZoneIds());
 List<String> gmt = new ArrayList<>(ZoneId.getAvailableZoneIds());
最后,我得到一个错误:

java.time.DateTimeException: Invalid ID for region-based ZoneId, invalid format: America/El Salvador
    at java.time.ZoneRegion.checkName(ZoneRegion.java:151)
    at java.time.ZoneRegion.ofId(ZoneRegion.java:116)
    at java.time.ZoneId.of(ZoneId.java:411)
    at java.time.ZoneId.of(ZoneId.java:359)
    at project.Bot.getOffset(Bot.java:5822)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at project.Bot.getOutputZone(Bot.java:6070)
    at project.Bot.getTimeZone(Bot.java:6041)
    at project.Bot.onUpdateReceived(Bot.java:399)
在调试过程中,由于这一行上的
getOffset()
方法
ZonedDateTime zdt=LDT.atZone(ZoneId.of(zone))我在哪里设置
美国/萨尔瓦多
。如果我写的是《美国/萨尔瓦多》,那么我就没有这个问题


但是为什么我不能用空格代替下划线呢?

时区ID实际上不是由Java标准定义的,而是在Java之外的一个数据集中定义的,该数据集称为,是一个公共域时区标准,旨在实现应用程序和编程语言之间的互操作性

时区名称背后的规则是:

时区以“区域/位置”的形式具有唯一的名称,例如“美国/纽约”。还选择使用英文名称或等效名称,并省略标点符号和常用后缀下划线字符用于代替空格。在位置名称中出现连字符的地方使用连字符。区域和位置名称的最大长度为14个字符

因此,下划线是基于格式需要的,因此使用带空格的时区而不是下划线将不起作用,这不是因为Java不支持它,而是因为它没有匹配的tz条目

如果要从tz转换为干净显示,可以用空格替换下划线,反之亦然,将干净显示转换回时区id


时区ID实际上不是由Java标准定义的,而是在Java之外的数据集中定义的,该数据集称为,是一个公共域时区标准,旨在实现应用程序和编程语言之间的互操作性

时区名称背后的规则是:

时区以“区域/位置”的形式具有唯一的名称,例如“美国/纽约”。还选择使用英文名称或等效名称,并省略标点符号和常用后缀下划线字符用于代替空格。在位置名称中出现连字符的地方使用连字符。区域和位置名称的最大长度为14个字符

因此,下划线是基于格式需要的,因此使用带空格的时区而不是下划线将不起作用,这不是因为Java不支持它,而是因为它没有匹配的tz条目

如果要从tz转换为干净显示,可以用空格替换下划线,反之亦然,将干净显示转换回时区id


区域ID由定义。如果它是用下划线定义的,它需要一个下划线。@Compass,噢,这很有意义。非常感谢。我想如果我改变它,我会得到另一个结果。如果它是用下划线定义的,它需要一个下划线。@Compass,噢,这很有意义。非常感谢。我想如果我更改它,会得到另一个结果。是的,为了解决这个问题,我在使用getOffset()方法之前将空格替换为下划线。是的,为了解决这个问题,我在使用getOffset()方法之前将空格替换为下划线。
newList_utc.stream().filter(it -> it.contains("El Salvador")).collect(Collectors.toList());
newList_utc.stream().filter(it -> it.contains("America/El Salvador")).map(Class::getOffset).collect(Collectors.toList());

...
...

private static String getOffset(String zone) {
       ZonedDateTime zdt = LDT.atZone(ZoneId.of(zone));
       return zdt.getOffset().getId().replace("Z", "+00:00");
}
java.time.DateTimeException: Invalid ID for region-based ZoneId, invalid format: America/El Salvador
    at java.time.ZoneRegion.checkName(ZoneRegion.java:151)
    at java.time.ZoneRegion.ofId(ZoneRegion.java:116)
    at java.time.ZoneId.of(ZoneId.java:411)
    at java.time.ZoneId.of(ZoneId.java:359)
    at project.Bot.getOffset(Bot.java:5822)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at project.Bot.getOutputZone(Bot.java:6070)
    at project.Bot.getTimeZone(Bot.java:6041)
    at project.Bot.onUpdateReceived(Bot.java:399)