如何在没有Joda Time的情况下在Java 7中正确处理夏令时?

时间:2015-11-01 18:18:23

标签: java datetime calendar timezone dst

在标记之前,重复阅读它不能使用Joda Time和Java 8 time.util *

我试图获取启用了DST的国家/地区的当前日期。由于时区有[local-millis] = [UTC-millis] + [offset-millis]所以我添加了DST_OFFSET以便在启用DST的国家/地区获得时间,就像在Linux机器GMT_TIME + LOCAL_TIME_ZONE_OFFSET + DST_OFFSET上完成一样来获取当前本地时间。

打印当前时间Istanbul的代码,该时间当前已启用DST 1小时。

public class DstInstanbul {

    public static void main(String...args){

        Calendar calendar = Calendar.getInstance();

        TimeZone timeZone = TimeZone.getTimeZone("Europe/Istanbul");

        calendar.setTimeZone(timeZone);

        calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());


        SimpleDateFormat simpleDateFormatLocal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormatLocal.setTimeZone(TimeZone.getTimeZone("Europe/Istanbul"));

        System.out.println("Current date and time : " + simpleDateFormatLocal.format(calendar.getTime()));


       System.out.println("Current date and time : " + simpleDateFormatLocal.format(calendar.getTime()));
       System.out.println("The TimeZone is : " + calendar.getTimeZone().getID());

    }
}

哪个给了我正确的输出

Current date and time : 2015-11-01 20:49:54
The Hour of the Day is : 20
The TimeZone is : Europe/Istanbul

但由于上面的代码不是通用的,所以我尝试添加以下行,这样如果只启用了日光,那么只添加 dstSaving所以我用

更改了以下calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());
if (timeZone.inDaylightTime(new Date())){
            calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());
       }

但问题是,如果我这样做,我得到没有任何夏令时的输出。并且打印System.out.println(timeZone.inDaylightTime(new Date()));给了我错误的结果,但结果却是夏令时,正如您在此链接中看到的那样Istanbul clock

Current date and time : 2015-11-01 19:54:49
The TimeZone is : Europe/Istanbul.

时区Brazil的相同逻辑让我对inDaylightTime真实,但现在提前一小时显示结果

以讨论方式排序的所有代码的Ideone链接1. https://ideone.com/4NR5Ym 2。https://ideone.com/xH7vhp 3。https://ideone.com/tQenb5

我的问题是timeZone.inDaylightTime(new Date())与伊斯坦布尔时区有什么问题。它为什么显示错误。为什么对于巴西,即使inDaylightTime成立,我也没有获得当前的DST时间。 处理这种情况的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

你不应该这样做:

calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());

你也不应该这样做:

if (timeZone.inDaylightTime(new Date())){
    calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());
}

您无需手动调整时间。它会根据您格式化的日期自动完成。调用add只会移动您正在使用的瞬时时间点。

删除这些行,并更新你的JVM以接受最新的土耳其DST更改(正如Monz在他的回答中所述),你应该很高兴。

答案 1 :(得分:3)

今天土耳其似乎有一些关于时区和夏令时的问题。

这可能是因为Turkey has changed the date for the daylight savings switch from November 1 to November 8.

JVM中的时区数据可能与更改无关。 Oracle has an update for their JVM.

从上面的链接下载的时区数据更新程序是一个可执行的jar文件。要在unix主机上更新JVM:

sudo java -jar tzupdater.jar --update --location http://www.iana.org/time-zones/repository/tzdata-latest.tar.gz

该工具似乎无法在更新时输出任何内容,因此要验证运行:

java -jar tzupdater.jar --version 

土耳其更新版的时区数据版本为tzdata2015g