在 Java 中获取时区的夏令时转换日期
Posted
技术标签:
【中文标题】在 Java 中获取时区的夏令时转换日期【英文标题】:Get Daylight Saving Transition Dates For Time Zones in Java 【发布时间】:2021-03-18 12:22:38 【问题描述】:我想知道用 Java 最简单的方法来获取未来夏令时将发生变化的日期列表。
执行此操作的一种相当不雅的方法是简单地迭代数年的天数,并针对 TimeZone.inDaylightTime() 对其进行测试。这会起作用,而且我不担心效率,因为它只需要在我的应用程序每次启动时运行,但我想知道是否有更简单的方法。
如果您想知道我为什么要这样做,那是因为我有一个 javascript 应用程序需要处理包含 UTC 时间戳的第三方数据。我想要一种在客户端从 GMT 转换为 EST 的可靠方法。请参阅Javascript -- Unix Time to Specific Time Zone 我已经编写了一些 javascript 可以做到这一点,但我想从服务器获取精确的转换日期。
【问题讨论】:
看到这个问题:***.com/questions/581581/… 【参考方案1】:Joda Time (一如既往)由于DateTimeZone.nextTransition
方法使这变得非常容易。例如:
import org.joda.time.*;
import org.joda.time.format.*;
public class Test
public static void main(String[] args)
DateTimeZone zone = DateTimeZone.forID("Europe/London");
DateTimeFormatter format = DateTimeFormat.mediumDateTime();
long current = System.currentTimeMillis();
for (int i=0; i < 100; i++)
long next = zone.nextTransition(current);
if (current == next)
break;
System.out.println (format.print(next) + " Into DST? "
+ !zone.isStandardOffset(next));
current = next;
输出:
2009 年 10 月 25 日 01:00:00 进入夏令时?错误的 2010 年 3 月 28 日 02:00:00 进入夏令时?真的 2010 年 10 月 31 日 01:00:00 进入夏令时?错误的 2011 年 3 月 27 日 02:00:00 进入夏令时?真的 2011 年 10 月 30 日 01:00:00 进入夏令时?错误的 2012 年 3 月 25 日 02:00:00 进入夏令时?真的 2012 年 10 月 28 日 01:00:00 进入夏令时?错误的 2013 年 3 月 31 日 02:00:00 进入夏令时?真的 2013 年 10 月 27 日 01:00:00 进入夏令时?错误的 2014 年 3 月 30 日 02:00:00 进入夏令时?真的 2014 年 10 月 26 日 01:00:00 进入夏令时?错误的 2015 年 3 月 29 日 02:00:00 进入夏令时?真的 2015 年 10 月 25 日 01:00:00 进入夏令时?错误的 ...使用 Java 8,您可以使用 ZoneRules
及其 nextTransition
和 previousTransition
方法获得相同的信息。
【讨论】:
+1 表示“样本来了”的想法(当然还有其他答案) 当然,预测这么远是相当投机的。美国最近修改了 DST 日期,并且可能会再次修改。 今年第一个 DST 过渡日期是 2010 年 3 月 14 日(发生在几天前)。但是您的脚本指定了 28-Mar-2010。我错过了什么吗? @Silence:现在是伦敦的 3 月 28 日,这是代码中指定的时区。不是每个人都在美国... @bluelurker:在 Java 8 中,您可以使用ZoneRules.nextTransition
和 ZoneRules.previousTransition
。我在答案中编辑了一个链接。【参考方案2】:
java.time
现代答案使用 java.time,现代 Java 日期和时间 API。
ZoneId zone = ZoneId.of("Europe/London");
ZoneRules rules = zone.getRules();
ZonedDateTime now = ZonedDateTime.now(zone);
ZoneOffsetTransition transition = rules.nextTransition(now.toInstant());
Instant max = now.plusYears(15).toInstant();
while (transition != null && transition.getInstant().isBefore(max))
System.out.println(transition);
transition = rules.nextTransition(transition.getInstant());
输出,缩写:
Transition[Overlap at 2019-10-27T02:00+01:00 to Z] Transition[Gap at 2020-03-29T01:00Z to +01:00] Transition[Overlap at 2020-10-25T02:00+01:00 to Z] Transition[Gap at 2021-03-28T01:00Z to +01:00] Transition[Overlap at 2021-10-31T02:00+01:00 to Z] Transition[Gap at 2022-03-27T01:00Z to +01:00] Transition[Overlap at 2022-10-30T02:00+01:00 to Z] (cut) Transition[Overlap at 2033-10-30T02:00+01:00 to Z] Transition[Gap at 2034-03-26T01:00Z to +01:00]
不过,我不会对数据过于信任。我不确定英国脱欧后(以及欧盟可能在 2021 年放弃夏令时 (DST) 之后)英国的时间会发生什么变化。
链接: Oracle tutorial: Date Time 解释如何使用 java.time。
【讨论】:
以上是关于在 Java 中获取时区的夏令时转换日期的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Dynamics CRM 中获取时区的夏令时开始和结束?
Calendar日期类详解SimpleDateFormat时区Date夏令时常用方法,日期差获取当前时间