Java 如果DST格式不正确,如何获取时区偏移?

Java 如果DST格式不正确,如何获取时区偏移?,java,timezone,java-time,timezone-offset,Java,Timezone,Java Time,Timezone Offset,我还没有找到一种不受夏令时干扰的方法来获得时区偏移 LocalDateTime dt = LocalDateTime.now(); ... ZoneId zone = ZoneId.of(s); ZonedDateTime zdt = dt.atZone(zone); ZoneOffset offset = zdt.getOffset(); 这似乎是可行的,但初始数据时间可能会受到DST的影响 还有一点: int rawOffset = tZone.getRawOffset(); 然而,这始

我还没有找到一种不受夏令时干扰的方法来获得时区偏移

LocalDateTime dt = LocalDateTime.now();
...
ZoneId zone = ZoneId.of(s);
ZonedDateTime zdt = dt.atZone(zone);
ZoneOffset offset = zdt.getOffset();
这似乎是可行的,但初始数据时间可能会受到DST的影响

还有一点:

int rawOffset = tZone.getRawOffset();
然而,这始终是一个正数,因此我们永远不会得到-05:00返回

所以我想要的是一种在没有DST干扰的情况下获得偏移量的方法。有什么想法吗?

使用

使用


根据Java API文档,TimeZone.getRawOffset将返回正确的历史偏移量

公共摘要int getRawOffset

返回要添加到UTC以获取此时区的标准时间的时间量(毫秒)。由于该值不受夏令时的影响,因此称为原始偏移

如果基础时区实现子类支持历史GMT偏移量更改,则该方法返回当前日期的原始偏移量值。例如,在檀香山,其原始偏移量在1947年从GMT-10:30更改为GMT-10:00,该方法始终返回-36000000毫秒,即-10小时

返回: 要添加到UTC的原始偏移时间量(以毫秒为单位)。 另见: Calendar.ZONE\u偏移量


from:

时区。根据Java API文档,getRawOffset将返回正确的历史偏移量

公共摘要int getRawOffset

返回要添加到UTC以获取此时区的标准时间的时间量(毫秒)。由于该值不受夏令时的影响,因此称为原始偏移

如果基础时区实现子类支持历史GMT偏移量更改,则该方法返回当前日期的原始偏移量值。例如,在檀香山,其原始偏移量在1947年从GMT-10:30更改为GMT-10:00,该方法始终返回-36000000毫秒,即-10小时

返回: 要添加到UTC的原始偏移时间量(以毫秒为单位)。 另见: Calendar.ZONE\u偏移量


from:

首先,请记住,即使是标准的补偿也会随着时间的推移而变化,这主要是因为政府、法律和其他外部因素

这就是为什么API需要一个瞬间作为参考:知道那个特定时刻的标准偏移量是多少,不管这个瞬间是在过去、现在还是将来。在不知道时间的情况下,你不能说偏移量是多少。这就是为什么它是正确的

但是正如您在评论中所说的,您不想依赖Instant.now,我已经完成了下面的代码-请记住,由于上述原因,解决方案不是100%理想的。这是我按照你的标准做的最好的了

您可以使用java.time.zone.ZoneRules类来实现这一点,该类可以直接从ZoneId实例获得:

// pick a timezone with DST
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// get rules
ZoneRules rules = zone.getRules();
// check if offset changes over time (if it returns false, it means is not fixed, so it has DST)
System.out.println(rules.isFixedOffset()); // false
在上面的代码中,rules.isFixedOffset返回false,这意味着相应时区的偏移量随时间而变化,因此它有DST变化

要知道这些DST更改何时发生,必须获取所有转换:

// get all transitions (all dates where DST starts or ends)
List<ZoneOffsetTransition> transitions = rules.getTransitions();
transitions.stream().forEach(System.out::println);
在本例中,它打印-03:00,这是非DST时美国/圣保罗时区的正常偏移量

PS:请注意,DST甚至标准偏移量会随时间变化很大

仅仅因为补偿在今天是一个,并不意味着它总是一样的:政府可以在任何时候改变补偿,而且在过去的日期,比如1900年之前,补偿比今天要混乱得多,每个城市都有自己的时间,比如-03:06:28等等


上面的代码获取当前时区规则的标准非DST偏移量。如果您想知道30年前的非DST偏移量是多少,可以使用30年前的瞬间作为参数。

首先,请记住,即使是标准偏移量,偏移量也会随时间而变化,这主要是因为政府、法律和其他外部因素

这就是为什么API需要一个瞬间作为参考:知道那个特定时刻的标准偏移量是多少,不管这个瞬间是在过去、现在还是将来。在不知道时间的情况下,你不能说偏移量是多少。这就是为什么它是正确的

但是正如您在评论中所说的,您不想依赖Instant.now,我已经完成了下面的代码-请记住,由于上述原因,解决方案不是100%理想的。这是我按照你的标准做的最好的了

您可以使用java.time.zone.ZoneRules类来实现这一点,该类可以直接从ZoneId实例获得:

// pick a timezone with DST
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// get rules
ZoneRules rules = zone.getRules();
// check if offset changes over time (if it returns false, it means is not fixed, so it has DST)
System.out.println(rules.isFixedOffset()); // false
在上面的代码中,rules.isFixedOffset返回false,这意味着相应时区的偏移量随时间而变化,因此它有DST变化

要知道这些DST更改何时发生,必须获取所有转换:

// get all transitions (all dates where DST starts or ends)
List<ZoneOffsetTransition> transitions = rules.getTransitions();
transitions.stream().forEach(System.out::println);
在本例中,它将打印-03:00,这是在打印时美国/圣保罗时区的正常偏移量 这不是DST

PS:请注意,DST甚至标准偏移量会随时间变化很大

仅仅因为补偿在今天是一个,并不意味着它总是一样的:政府可以在任何时候改变补偿,而且在过去的日期,比如1900年之前,补偿比今天要混乱得多,每个城市都有自己的时间,比如-03:06:28等等


上面的代码获取当前时区规则的标准非DST偏移量。如果您想知道30年前的非DST偏移量是多少,可以使用30年前的瞬间作为参数。

我不明白您想要实现什么。分区没有固定的偏移。偏移量取决于日期。请注意:getRawOffset接近您想要的值,并且在适当的情况下应该返回负值。不同之处在于,你可能无法从中获得历史上正确的甚至相关的价值观。你想实现什么?这听起来像是您试图自己重新计算一些东西,而这些东西可能应该由某个java.time类来处理。你需要这些信息做什么?如果我理解正确,你想知道时区的偏移量是多少,而不是DST,对吗?而且它必须独立于当前日期是什么?没有“时区偏移量,当它不是DST时”“独立于当前日期”。时区的定义是过去、现在和将来的变化的历史集合,以抵消特定区域使用的UTC。所以没有所谓的“正常偏移”,没有基线偏移,这就是你想要的。你的问题可能源于对时区的一个普遍的基本误解:它们不是真实的,不是自然的。区域和补偿是人类创造的,特别是反复无常的政客,他们经常改变规则。我不明白你想要实现什么。分区没有固定的偏移。偏移量取决于日期。请注意:getRawOffset接近您想要的值,并且在适当的情况下应该返回负值。不同之处在于,你可能无法从中获得历史上正确的甚至相关的价值观。你想实现什么?这听起来像是您试图自己重新计算一些东西,而这些东西可能应该由某个java.time类来处理。你需要这些信息做什么?如果我理解正确,你想知道时区的偏移量是多少,而不是DST,对吗?而且它必须独立于当前日期是什么?没有“时区偏移量,当它不是DST时”“独立于当前日期”。时区的定义是过去、现在和将来的变化的历史集合,以抵消特定区域使用的UTC。所以没有所谓的“正常偏移”,没有基线偏移,这就是你想要的。你的问题可能源于对时区的一个普遍的基本误解:它们不是真实的,不是自然的。区域和偏移是由人类创建的,特别是由经常更改规则的反复无常的政客创建的。但是您使用的是Instant.now,它受Dayllight Savings time的影响。Instant.now表示不知道DST或时区的当前时间,所以它不能被DST污染,除非你的本地时钟因为时区的诡计而出错,那么所有的赌注都没有了。所以我玩了这个,这似乎是我想要的。然而,你能解释一下为什么需要Instant.now吗?为什么任何日期都需要查找时区与UTC的偏移量?为什么日期很重要?如果您想引用“关于标准偏移量如何随时间变化的历史信息”,可以使用instant。历史上,一个国家或地区多次改变其标准偏移量。我相信当我还是个孩子的时候,西班牙和我的国家在不同的区域,但现在它在同一个区域。这个答案包含了我最喜欢的代码片段。它没有包含我最喜欢的解释。我们可以使用更多的后者,请…但您使用的是Instant.now,它受Dayllight储蓄时间的影响。Instant.now表示当前时间,不知道DST或时区,因此它不能被DST污染,除非您的本地时钟因时区诡计而出错,不管怎样,所有的赌注都输掉了。所以我玩了这个,这似乎是我想要的。然而,你能解释一下为什么需要Instant.now吗?为什么任何日期都需要查找时区与UTC的偏移量?为什么日期很重要?如果您想引用“关于标准偏移量如何随时间变化的历史信息”,可以使用instant。历史上,一个国家或地区多次改变其标准偏移量。我相信当我还是个孩子的时候,西班牙和我的国家在不同的区域,但现在它在同一个区域。这个答案包含了我最喜欢的代码片段。我
t没有包含我最喜欢的解释。我们可以使用更多的后者,请…我们需要使用其他过时的班级时区吗?现代班级有解决办法吗?我们是否需要使用其他过时的班级时区?现代课堂有解决方案吗?你已经彻底研究过了!美好的与其他两个答案相比,您的方法的优势是什么?如果我在1987年找不到一个区域的过渡,那么,我想这只是意味着我可以在那一年的任何一个瞬间,查询它的偏移量,你同意吗?这是很好的信息!JVM中包含了所有这些转换,这让我大吃一惊。不过,我相信约阿希姆·绍尔的答案要简单得多。谢谢你的教育@奥列夫。OP告诉我,我不想依赖Instant.now,为了得到当前的标准偏移量,最后一种过渡方法是我能得到的最好方法。我知道这不是一个完美的解决方案,因为补偿会随着时间的推移而变化,理想的情况是始终有一个日期/时间参考。因此,这个解决方案是在不依赖即时的情况下获得当前标准偏移量的最佳方案。现在,但要获得过去的偏移量,当然需要日期/时间参考,我承认我的解决方案并不理想。根据:两个偏移量之间的转换通常是夏时制转换的结果。所以这不是100%保证,但在UTC发生后,我们可以假设大多数时间它们都与DST相关。如果不是,我想知道API是如何决定什么是标准的。@markthegrea请记住,这个解决方案并不理想,我已经更新了答案,解释说,这是我所拥有的最好的解决方案,而不必依赖即时。现在正如你在评论中所说的。但约阿希姆的答案是正确的,因为你必须始终有一个瞬间作为参考,才能知道偏移量是多少。我还必须承认,我完成这段代码只是为了挑战……你已经彻底研究过了!美好的与其他两个答案相比,您的方法的优势是什么?如果我在1987年找不到一个区域的过渡,那么,我想这只是意味着我可以在那一年的任何一个瞬间,查询它的偏移量,你同意吗?这是很好的信息!JVM中包含了所有这些转换,这让我大吃一惊。不过,我相信约阿希姆·绍尔的答案要简单得多。谢谢你的教育@奥列夫。OP告诉我,我不想依赖Instant.now,为了得到当前的标准偏移量,最后一种过渡方法是我能得到的最好方法。我知道这不是一个完美的解决方案,因为补偿会随着时间的推移而变化,理想的情况是始终有一个日期/时间参考。因此,这个解决方案是在不依赖即时的情况下获得当前标准偏移量的最佳方案。现在,但要获得过去的偏移量,当然需要日期/时间参考,我承认我的解决方案并不理想。根据:两个偏移量之间的转换通常是夏时制转换的结果。所以这不是100%保证,但在UTC发生后,我们可以假设大多数时间它们都与DST相关。如果不是,我想知道API是如何决定什么是标准的。@markthegrea请记住,这个解决方案并不理想,我已经更新了答案,解释说,这是我所拥有的最好的解决方案,而不必依赖即时。现在正如你在评论中所说的。但约阿希姆的答案是正确的,因为你必须始终有一个瞬间作为参考,才能知道偏移量是多少。我也必须承认我完成这段代码只是为了挑战。。。