繁体   English   中英

Java夏令时问题

[英]problems with Java daylight savings time

我有一个需要识别时区的Java应用程序。 当我使用Unix时代的时间并尝试将其转换为用于Oracle SQL调用的时间戳时,它获取的是正确的时区,但是时区的“ useDaylightTime”值不正确,即,当前正在返回“ true” ,当我们不在DST时(我在佛罗里达州TZ的“ America / New_York”)。

它运行在Red Hat Linux Enterprise 6上,据我所知,它正确设置了时区,例如'date'返回:2012年11月28日星期三EST

我还可以使用'zdump'实用程序看到'isdst'的当前值为0。

我的Java版本是1.6.0_31。

我已经在Google上搜索了此文件,并看到了造成此问题的众多问题,但是其中许多问题只是说要手动设置TZ,但我的问题不是TZ,而是默认TZ的“ isDaylight”设置为“ true”的事实。 。 我相信这使我的查询返回的数据减少了一个小时(我可以看到)。

这是我运行过的简单代码段,试图以最简单的方式重现此代码段:

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”,则它的确会返回“ isDaylight”设置为False的TZ。 但这不是一个好的解决方案。

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

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

查询该表时,我使用的是使用日历项的准备好的语句,其唯一目的是尝试操纵时区。 最重要的是,在应用“默认”时区之后,我正在使用“ getTimeInMillis”方法作为开始时间和结束时间进行pstmt.setTimestamp()调用。 日志输出显示实际上它输入了正确的毫秒数,但是返回的SQL结果显然相差一小时!

我仍在尝试验证数据插入端也没有问题。

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

时区useDaylightTime值不正确,即当我们不在DST中时,当前返回“ true”

我认为您将useDaylightTimeinDaylightTime混淆了。 前者告诉您将来的夏时制和标准时间之间是否存在过渡,而不是您处于过渡的哪个方面。 例如,对于中国时区,它返回false,因为中国不调整夏令时,但是对于大多数美国时区,它返回true,因为大多数美国州( 亚利桑那州除外)都遵守夏令时。

inDaylightTime

 public abstract boolean inDaylightTime(Date date) 

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

useDaylightTime

 public abstract boolean useDaylightTime() 

查询此TimeZone是否使用夏时制。 如果基础的TimeZone实现子类支持历史和将来的夏时制时间表更改,则此方法引用最后一个已知的夏时制规则,该规则可以作为将来的预测,并且可能与当前规则不同。 如果还应考虑当前规则,请考虑调用observesDaylightTime()

如果要禁用夏令时计算,则必须将时区设置为EST。 否则,将根据为AMERICA / NEW_YORK设置的默认时区来计算时间

       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

我找到了一种确保忽略夏令时的方法

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

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

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)); 
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM