问题
Is it possible to get the previous and next DST transition timestamp with the Java Calendar/Date/TimeZone API?
With Joda-Time
I can write:
DateMidnight today = new DateMidnight(2009, 2, 24);
DateTimeZone zone = today.getZone();
DateTime previousTransition =
new DateTime(zone.previousTransition(today.getMillis()));
// 2008-10-26T02:59:59.999+02:00 for Europe/Berlin
System.out.println(previousTransition);
DateTime nextTransition =
new DateTime(zone.nextTransition(today.getMillis()));
// 2009-03-29T03:00:00.000+02:00 for Europe/Berlin
System.out.println(nextTransition);
Is there way to do this with the standard Java APIs?
回答1:
There's no such functionality in java Date/Calendar/TimeZone API
回答2:
The best I came up with, when I needed such functionality, is to use a Calendar and iterate through entire year, in specified time zone, and ask if each hour of each day is it the begging or ending of DST.
You have to do it like that because on Sun's JVM, the implementation of TimeZone (sun.util.calendar.ZoneInfo) holds data about time zone transitions in some kind of "compiled" form.
Code goes something like this:
public class Dst {
Date start;
Date end;
public static Dst calculate(TimeZone tz, int year) {
final Calendar c = Calendar.getInstance(tz);
c.setLenient(false);
c.set(year, Calendar.JANUARY, 1, 1, 0, 0);
c.set(Calendar.MILLISECOND, 0);
if (tz.getDSTSavings() == 0) {
return null;
}
Dst dst = new Dst();
boolean flag = false;
do {
Date date = c.getTime();
boolean daylight = tz.inDaylightTime(date);
if (daylight && !flag) {
flag = true;
dst.start = date;
}
else if (!daylight && flag) {
flag = false;
dst.end = date;
}
c.add(Calendar.HOUR_OF_DAY, 1);
}
while (c.get(Calendar.YEAR) == year);
return dst;
}
}
Of course, it would make sense to cache/memoize the result of these calculations etc.
Hope this helps.
回答3:
With Java 8 you can use the
ZoneRules#nextTransition(Instant)
&
ZoneRules#previousTransition(Instant)
methods to do the same thing.
https://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html
回答4:
Yes, there is an indirect way to retrieve this from Java API. Check this out and let me know if this works for the problem:
http://monisiqbal.blogspot.com/2009/12/retrieving-time-zones-dst-information.html
This should give you the required info for the current year, you can easily do the same for previous years if you want to.
来源:https://stackoverflow.com/questions/581581/find-dst-transition-timestamp-with-java-util-timezone