Find DST transition timestamp with java.util.TimeZone

℡╲_俬逩灬. 提交于 2020-01-03 16:47:32

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!