Java API to get daylight saving boundaries for a year
我有一个日期范围(开始和结束日期),需要知道这是否属于夏令时的变化。
是否有任何Java API可用于检查此代码或任何Java代码来实现此目的?
夏令时更改发生在每个国家/地区的不同日期,因此首先要知道的是您正在检查的时区的名称。
我正在使用Joda-Time和新的Java Date / Time API编写这个答案,并且都使用IANA的时区名称列表(格式为
对于下面的代码,我将使用
下面的代码显示了如何检查日期是否在夏令时,并找到DST更改发生时的下一个日期。因此,如果您有一个开始和结束日期,并想知道两者是否都在DST更改中,您可以检查两者是否都在DST中,并且还可以找到下一个和之前的DST更改(并检查日期是否介于两者之间)那些变化 - 我不清楚你应该如何进行检查)。
另请注意,Joda-Time处于维护模式并且正在被新API替换,因此我不建议使用它来启动新项目。甚至在joda的网站上也说:"请注意,Joda-Time被认为是一个很大程度上已经完成的项目。没有计划进行重大改进。如果使用Java SE 8,请迁移到java.time(JSR-310)。"
乔达时间
您可以使用
下面的代码检查日期是否在DST中,并且还查找DST更改将发生的下一个日期:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 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更改(而不是下一个),请调用
Java新的日期/时间API
如果您使用的是Java 8,则新的java.time API已经本地出现。
如果您使用Java <= 7,则可以使用ThreeTen Backport,这是Java 8的新日期/时间类的一个很好的后端。对于Android,还有ThreeTenABP(更多关于如何在这里使用它)。
以下代码适用于两者。
唯一的区别是包名称(在Java 8中是
代码与Joda-Time的版本非常相似。主要区别:
-
虽然Joda-Time有
isStandardOffset() 来检查日期是否在DST中,但新API有isDaylightSavings() 来检查日期是否在DST中。 -
Joda-Time直接在
DateTimeZone 类中提供方法,但新API有一个专用于其DST规则的类(java.time.zone.ZoneRules ) -
下一个和上一个转换的方法返回
java.time.zone.ZoneOffsetTransition 而不是直接返回日期(此对象提供有关DST更改的更多信息,如下所示)。
尽管存在这些差异,但这个想法非常相似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // 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更改而不是下一个更改,可以调用
当然有。还有不止一个。要使用的标准API是
很明显,您首先需要确定您想要的时区。
你标记了你的问题gmt,这很简单:GMT没有夏令时(夏令时),因此你的范围永远不会有转换。如果这是你的意思,你需要不再阅读。
北美和欧盟的夏令时转换日期并不相同,而在南半球,它们却完全不同。此外,许多时区根本不应用DST。因此,从
你标记了你的问题jodatime,是的,Joda-Time也应该是一个选项。
Note that Joda-Time is considered to be a largely"finished" project.
No major enhancements are planned. If using Java SE 8, please migrate
tojava.time (JSR-310).
引自Joda-Time主页。