现在我们有一个CS的系统(C: java, S: Oracle). 在下个月要把时间从夏令时转冬令时.由于之前没有考虑这个问题, 所以程序中都是不分时区的. 请问大家有没有遇到这个问题? 并有什么解决建议? 包括前台的java时间,如何保存这些信息, 后台Oracle如何处理等. 谢谢!!

解决方案 »

  1.   

    虽然不知道你有什么用处,但可以通过时区来实现,给个简单例子,希望能有帮助:
    public static void main(String[] args) {
      Calendar gmtlocal = new GregorianCalendar(TimeZone.getTimeZone("GMT+8"));
      gmtlocal.set(Calendar.YEAR, 2007);
      gmtlocal.set(Calendar.MONTH, 0);
      gmtlocal.set(Calendar.DAY_OF_MONTH, 1);
      gmtlocal.set(Calendar.HOUR_OF_DAY, 0);
      gmtlocal.set(Calendar.MINUTE, 0);
       
      Calendar gmt0 = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
      gmt0.setTimeInMillis(gmtlocal.getTimeInMillis());
      System.out.println(gmt0.get(Calendar.YEAR));
      
      SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      sf.setTimeZone(TimeZone.getTimeZone("GMT+12"));
      System.out.println(sf.format(gmtlocal.getTime()));
       
      sf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
      System.out.println(sf.format(gmtlocal.getTime()));
       
      sf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
      System.out.println(sf.format(gmtlocal.getTime()));  
     }
      

  2.   

    bao110908(讨厌蟑螂):我们国内是取消了. 
    shan1119(大天使,卐~解!) : 就是夏令时把时间向后拨一个小时, 冬令时反之.这个是在国外, 所以还有这个问题.sureyor(). 谢谢, 我看下. 我的主要用途是在客户端的程序用户可以选择是DST还是不是. 然后把这个保存起来, 通过SQL语句把这些信息保存到数据库中.
      

  3.   

    顺便问下, JDBC 如何保存和读取数据库timestamp with timezone的字段的时间?
      

  4.   

    http://blog.chinaunix.net/u/19782/showart_208715.html
      

  5.   

    Oracle
    3. How to check the database time zone ?
    ========================================
    Answer
    ------
    The DBTIMEZONE SQL function returns the value of the database time zone.SQL> SELECT DBTIMEZONE FROM DUAL;DBTIMEZONE
    --------------
    Europe/Lisbon@ Note that the database timezone is also included in both database_properties
    @ and props$ views:
    @ SQL> SELECT property_name, property_value
    @ FROM database_properties
    @ WHERE property_name='DBTIMEZONE';
    @ and
    @ SQL> SELECT name, value$
    @ FROM props$
    @ WHERE name='DBTIMEZONE';
    @ Be aware that you should not rely on these views because in case of db time zone
    @ change, these views reflect the new db time zone too early: they should reflect
    @ it only after database shutdown and restart.
      

  6.   

    谢谢sureyor() . 在oracle中,用 timestamp with time zone, 就可以了. 然后可以用TZH,TZM读取和保存timezone的信息. 现在不知道在JDBC中是如何从ResultSet中取得timezone的信息, 再查询中...
      

  7.   

    "JDBC中是如何从ResultSet中取得timezone的信息",不明白,SELECT DBTIMEZONE FROM DUAL这个SQL不行吗?
      

  8.   

    shan1119(大天使,卐~解!), 谢谢你给的信息!
      

  9.   

    sureyor(), 我的意思是在timestamp with time zone 这样的字段, 如何通过JDBC把保存的time zone信息拿到? 不是 DBTIMEZONE.
      

  10.   

    timestamp无法取得timezone的信息吧?
    除非你在生成timestamp的时候,将当时的timezone也保存下来
      

  11.   

    sureyor(): 
    ResultSet.getString(index) 这个可以把timezone的正确信息打印出来,比如:
    1999-12-1 11.0.0.0 -8:0可是我想得到的是一个时间对象, 而不是一个字符串.
      

  12.   

    ResultSet.getTimestamp().getTimezoneOffset()Time,Timezone都可以取到,然后剩下的可以用Calendar类来实现吧.
    Calendar.setTime()
    Calendar.setTimeZone()
    Calendar.add(Calendar.DATE, 1);//or -1不知道会不会有问题.
      

  13.   

    shan1119(大天使,卐~解!):
    ResultSet.getTimestamp().getTimezoneOffset(): The method getTimezoneOffset() from the type Date is deprecated. 这个方法不推荐了.我测试: 数据时间是: 01-12月-99 11.00.00.000000 上午 -08:00
    System.out.println("getTimezoneOffset: " + ResultSet.getTimestamp().getTimezoneOffset().getTimezoneOffset() / 60);
    打印出来是: 
    getTimezoneOffset: -8结果是对的.
      

  14.   

    对不起, 结果是不对了. 数据库时间01-12月-99 11.00.00.000000 上午 +09:00
    返回的时间却还是-8, 也就是一直是本地时间. getTimezoneOffset() 这个是静态方法. :(
      

  15.   

    try{              
    Class.forName("oracle.jdbc.driver.OracleDriver");
    String url = "jdbc:oracle:thin:@10.201.147.209:1521:chuden";
    Connection conn= DriverManager.getConnection(url,"gyomu","gyomu");
        Statement stmt=conn.createStatement();

        StringBuffer sql = new StringBuffer();
        sql.append(" select t,TO_char(t,'TZH:TZM') zone from tbltest");
       
    ResultSet rs = stmt.executeQuery(sql.toString()); while(rs.next()){
    Timestamp t = rs.getTimestamp("t");
    String zone = rs.getString("zone");
    Calendar c = Calendar.getInstance();
    c.setTime(t);
    TimeZone tz = TimeZone.getTimeZone("GMT"+zone);

    c.setTimeZone(tz);
    System.out.println(c.getTimeZone());
    }

    }catch(Exception e){
    e.printStackTrace();
    }
      

  16.   

    shan1119(大天使,卐~解!), 谢谢! 这样是可以得到timezone, 但是SQL都不可能写个TO_char(t,'TZH:TZM') 在查询语句中啊. 所以这不是个好办法:)
      

  17.   

    如果你想在java里直接从取到的Timestamp中得到timezone的信息好象不可能,我看了下Timestamp的构造方法,好象没有timezone的信息.
      

  18.   

    shan1119, 好像是的. 但是我奇怪的就是ResultSet.getString(index)可以看到正确的时区, getTimestamp或其他的就不可以
      

  19.   

    我用ORACLE的时候时间保存成字符的,感觉很方便。
      

  20.   

    我这里不可以, 原因一个是这已经是一个运行的系统了. 设计开始的时候没有考虑这个问题, 所以现在才来改, 下个月就要夏冬令时转换. 二是这里的时间会有很多计算, 所以不把时间保存成字符串, 计算的时候再转换成时间. Oracle这边应该是没有什么问题了. 主要是JAVA这边 :(, 首先就是JDBC, 然后是我们系统自己的一些修改.
      

  21.   

    哦,取字符串啊,没注意到.
    要是那样的话可以截取字符串,它的格式是一定的,应该能取得到.
    String zone = rs.getString("t").substring(29);这块改成这个,就不用加那个sql了.
      

  22.   

    比如: ResultSet.getString(index), 结果是:
    1999-12-1 11.0.0.0 -8:0这样可以取得timezone的信息, 可是这样去处理不好吧?
      

  23.   

    数据库的格式是一样的, 就是不知道ResultSet.getString(index), 对于不同数据库或不同的JDBC的版本.这个tostring的结果是不相同的我想, 至少不是都相同.  说这个方法不好. 如果实在没有办法, 就这么搞了 :(
      

  24.   

    http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/text/SimpleDateFormat.html#rfc822timezone再给个参考资料,你自己慢慢折腾吧,或许能用上,看你自己的了 :)