与Java日光节约时间问题(problems with Java daylight savings

2019-07-04 05:34发布

我有一个需要被认识到的时区的Java应用程序。 当我把一个Unix纪元时间,并尝试将其转换成时间戳使用针对Oracle SQL调用,它得到正确的时区,但该时区“useDaylightTime”值是不正确的,也就是说,它目前正在返回“真”当我们在DST不是(我在佛罗里达TZ“美国/纽约”)。

这是Red Hat Linux上运行的企业6家,而据我所知,这正确设置的时区,例如“日期”返回:星期三11月28日十二时30分12秒美国东部时间2012

我还可以看到,使用'zdump的效用,对于“isdst”时,当前值为0。

我的Java版本为1.6.0_31。

我用Google搜索这一点,并看到了这一点已经引起了许多问题,但很多只是说要手动设置TZ,但我的问题是不是TZ,但默认TZ有“isDaylight”设置为“真”的事实。 我相信这是造成我的查询返回是一个小时(我可以看到它是)数据。

以下是我已经运行,试图以尽可能简单的方式重现这个简单的代码块:

public class TZdefault {

    public static void main(String[] args) throws IOException {

            long startTime = System.currentTimeMillis()/1000;

            Calendar start = Calendar.getInstance();
            start.setTimeInMillis(startTime);

            start.setTimeZone(TimeZone.getDefault());

            System.out.println("Start UTC: " + start + "ms: " + start.getTimeInMillis());
            System.out.println("use daylight: " + start.getTimeZone().useDaylightTime());

    } // end main


}  // end class

最后一两件事。 如果在我的代码设置TZ为“EST”,它当然有设置为False“isDaylight”返回TZ。 但是,这并不是一个很好的解决方案。

我想添加一些细节,我一直希望能隐藏。

我有一个Oracle 11g数据库使用TIMESTAMP WITH TIMEZONE字段的记录。 我只是做JDBC查询,其中两个参数的使用之间的开始时间戳和结束时间戳。

当我查询这个表,我使用的是使用日历项,其唯一目的是试图操纵时区一个准备好的声明。 底线是,我做的使用开始和结束时间的“getTimeInMillis”方法“默认”时区应用后pstmt.setTimestamp()调用。 日志输出显示,实际上它是把在正确的毫秒,但返回的SQL结果显然是关闭一小时正好!

我仍然试图验证是否有没有在数据插入侧也是一个问题。

但我有很多的调试信息,它看起来像我要求我的JDBC查询正确的时间。

Answer 1:

时区useDaylightTime值是不正确的,也就是说,它目前正在返回“真”,当我们在DST不

我想你混淆useDaylightTimeinDaylightTime 。 前者告诉你是否有在未来的过渡你在日光时间与标准时间之间的过渡,而不是哪一方。 例如,由于中国不调整夏令时它返回中国时区假的,但因为大多数美国的州(除了它返回对于大多数美国时区真亚利桑那州 )确实观察到夏令时。

inDaylightTime

 public abstract boolean inDaylightTime(Date date) 

查询给定日期是否是夏令时在该时区。

VS

useDaylightTime

 public abstract boolean useDaylightTime() 

如果这个时区使用夏令时,查询。 如果底层TimeZone实现子类支持历史和未来的夏令时安排的变化,这种方法是指最后已知的夏令时规则,可以是一个未来的预测,可能不一样的当前规则。 考虑调用observesDaylightTime()如果当前的规则也应考虑在内。



Answer 2:

如果您希望禁用夏令时计算,则必须设置时区到EST。 否则,否则时间将根据对美国/纽约默认时区设置来计算

       TimeZone zoneEST = TimeZone.getTimeZone("EST"); 
       System.out.println(zoneEST.getDSTSavings());  //0 hour
       System.out.println(zoneEST.getRawOffset());  //5 hour
       TimeZone.setDefault(zoneEST);
       System.out.println("");

       TimeZone zoneNY = TimeZone.getTimeZone("America/New_York");
       System.out.println(zoneNY.getDSTSavings()); // 1 hour
       System.out.println(zoneNY.getRawOffset()); // 5 hour


Answer 3:

我已经找到了一种方法,以确保夏令被忽略

TimeZone tz = TimeZone.getTimeZone("GMT");
TimeZone.setDefault(tz);
GregorianCalendar calendar;
calendar = new GregorianCalendar();

您创建GregorianCalendar对象之前,设置时区



Answer 4:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class TimeZoneTest {
    public static void main(String[] argv) throws ParseException {

        SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");

        String dateInString = "22-01-2015 10:15:55 AM";
        Date date = formatter.parse(dateInString);
        TimeZone tz = TimeZone.getDefault();

        // From TimeZone Asia/Singapore
        System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
        System.out.println("TimeZone : " + tz);
        System.out.println("Date : " + formatter.format(date));

        // To TimeZone America/New_York
        SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
        TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
        sdfAmerica.setTimeZone(tzInAmerica);

        String sDateInAmerica = sdfAmerica.format(date); // Convert to String first
        Date dateInAmerica = formatter.parse(sDateInAmerica);

        System.out.println("\nTimeZone : " + tzInAmerica.getID() + 
                                      " - " + tzInAmerica.getDisplayName());
        System.out.println("TimeZone : " + tzInAmerica);
        System.out.println("Date (String) : " + sDateInAmerica);
        System.out.println("Date (Object) : " + formatter.format(dateInAmerica)); 
    }

}


文章来源: problems with Java daylight savings time