gpt4 book ai didi

Java API 获得一年的夏令时界限

转载 作者:搜寻专家 更新时间:2023-11-01 01:49:38 25 4
gpt4 key购买 nike

我有一个日期范围(开始日期和结束日期)并且需要知道这是否属于夏令时转换。

是否有任何 Java API 可用于检查这个或任何 Java 代码来实现这个?

最佳答案

夏令时更改在每个国家/地区的不同日期发生,因此首先要知道您正在检查的时区的名称。

我正在使用 Joda-Time 和新的 Java 日期/时间 API 编写此答案,并且都使用 IANA's list of timezone names (格式为 Continent/City )。这两个 API 也避免使用 3-letter names因为它们是 ambiguous and not standard .

对于下面的代码,我将使用 America/Sao_Paulo (我住的时区,每年都有夏令时变化),但您可以将其替换为您想要的时区。

下面的代码向您展示了如何检查一个日期是否在 DST 中,以及如何找到下一个 DST 更改发生的日期。因此,如果您有开始日期和结束日期,并且想知道两者是否都在 DST 更改范围内,则可以检查两者是否都在 DST 范围内,还可以找到下一个和上一个 DST 更改(并检查日期是否介于这些更改 - 我不清楚应该如何进行检查)。


另请注意,Joda-Time 处于维护模式并且正在被新 API 取代,因此我不建议使用它启动新项目。即使在 joda's website它说:“请注意,Joda-Time 被认为是一个基本“完成”的项目。没有计划进行重大增强。如果使用 Java SE 8,请迁移到 java.time (JSR-310)。” .


Joda Time

您可以使用 org.joda.time.DateTimeZone类(class)。要了解所有可用时区,请调用 DateTimeZone.getAvailableIDs() .

下面的代码检查一个日期是否在 DST 中,并找到下一个 DST 更改发生的日期:

// create timezone object
DateTimeZone zone = DateTimeZone.forID("America/Sao_Paulo");

// check if a date is in DST
DateTime inDst = new DateTime(2017, 1, 1, 10, 0, zone);
// isStandardOffset returns false (it's in DST)
System.out.println(zone.isStandardOffset(inDst.getMillis()));
// check when it'll be the next DST change
DateTime nextDstChange = new DateTime(zone.nextTransition(inDst.getMillis()), zone);
System.out.println(nextDstChange); // 2017-02-18T23:00:00.000-03:00

// check if a date is in DST
DateTime noDst = new DateTime(2017, 6, 18, 10, 0, zone);
// isStandardOffset returns true (it's not in DST)
System.out.println(zone.isStandardOffset(noDst.getMillis()));
// check when it'll be the next DST change
nextDstChange = new DateTime(zone.nextTransition(noDst.getMillis()), zone);
System.out.println(nextDstChange); // 2017-10-15T01:00:00.000-02:00

如果您想查找上一个 DST 更改(而不是下一个),请调用 previousTransition()而不是 nextTransition() .


Java 新日期/时间 API

如果您使用的是 Java 8,则 new java.time API已经原生。

如果您使用的是 Java <= 7,您可以使用 ThreeTen Backport ,Java 8 的新日期/时间类的一个很好的反向移植。对于 Android,有 ThreeTenABP (更多关于如何使用它的信息 here)。

下面的代码适用于两者。唯一的区别是包名称(在 Java 8 中是 java.time,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp),但是类和方法名称是相同的。

代码与 Joda-Time 的版本非常相似。主要区别:

  • 虽然 Joda-Time 有 isStandardOffset()要检查日期是否在 DST 中,新的 API 有 isDaylightSavings()检查日期是否为夏令时。
  • Joda-Time 直接在 DateTimeZone 中提供方法类,但新 API 有一个专门用于 DST 规则的类 (java.time.zone.ZoneRules)
  • 下一个和上一个转换的方法返回一个 java.time.zone.ZoneOffsetTransition而不是直接返回日期(此对象提供有关 DST 更改的更多信息,如下所示)。

尽管存在所有这些差异,但想法非常相似:

// create timezone object
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// get the timezone's rules
ZoneRules rules = zone.getRules();

// check if a date is in DST
ZonedDateTime inDST = ZonedDateTime.of(2017, 1, 1, 10, 0, 0, 0, zone);
// isDaylightSavings returns true (it's in DST)
System.out.println(rules.isDaylightSavings(inDST.toInstant()));
// check when it'll be the next DST change
ZoneOffsetTransition nextTransition = rules.nextTransition(inDST.toInstant());
// getInstant() returns the UTC instant; atZone converts to the specified timezone
System.out.println(nextTransition.getInstant().atZone(zone)); // 2017-02-18T23:00-03:00[America/Sao_Paulo]

// you can also check the date/time and offset before and after the DST change
// in this case, at 19/02/2017, the clock is moved 1 hour back (from midnight to 11 PM)
ZonedDateTime beforeDST = ZonedDateTime.of(nextTransition.getDateTimeBefore(), nextTransition.getOffsetBefore());
System.out.println(beforeDST); // 2017-02-19T00:00-02:00
ZonedDateTime afterDST = ZonedDateTime.of(nextTransition.getDateTimeAfter(), nextTransition.getOffsetAfter());
System.out.println(afterDST); // 2017-02-18T23:00-03:00

// check if a date is in DST
ZonedDateTime noDST = ZonedDateTime.of(2017, 6, 1, 10, 0, 0, 0, zone);
// isDaylightSavings returns false (it's not in DST)
System.out.println(rules.isDaylightSavings(noDST.toInstant()));
// check when it'll be the next DST change
nextTransition = rules.nextTransition(noDST.toInstant());
// getInstant() returns the UTC instant; atZone converts to the specified timezone
System.out.println(nextTransition.getInstant().atZone(zone)); // 2017-10-15T01:00-02:00[America/Sao_Paulo]

// you can also check the date/time and offset before and after the DST change
// in this case, at 15/10/2017, the clock is moved 1 hour forward (from midnight to 1 AM)
beforeDST = ZonedDateTime.of(nextTransition.getDateTimeBefore(), nextTransition.getOffsetBefore());
System.out.println(beforeDST); // 2017-10-15T00:00-03:00
afterDST = ZonedDateTime.of(nextTransition.getDateTimeAfter(), nextTransition.getOffsetAfter());
System.out.println(afterDST); // 2017-10-15T01:00-02:00

如果您想查找上一个 DST 更改而不是下一个,您可以调用 rules.previousTransition()而不是 rules.nextTransition() .

关于Java API 获得一年的夏令时界限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44586105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com