posts - 89,  comments - 98,  trackbacks - 0

          What's your time zone?

          JAVA日期和時間類徹底解決(2)

          Page 2 of 3

          首先嘗試的解決方案 
          基于Java文檔信息和DateTest類的輸出結果,我打了一個最好的賭:JAVA虛擬機在第一次被運行時就自動設置了一個默認的時間區域(time zone)。為了驗證,我創建了一個ItsInitializer類,使得我的應用程序在被加載(launched)時便能夠運行它。以下是我的第一次嘗試:

          import java.util.TimeZone;
          import java.util.SimpleTimeZone;

          public class ItsInitializer {
            private static boolean s_initialized = false;

            private ItsInitializer() {
            }

            public static synchronized void initialize() {
              if (!s_initialized) {
                // Modifies the default time zone, disables the Daylight Saving Time.
                SimpleTimeZone dtz = (SimpleTimeZone) TimeZone.getDefault();
                dtz.setStartRule(0,0,0,0);
                dtz.setEndRule(0,0,0,0);
                TimeZone.setDefault(dtz);
                s_initialized = true;
              }
            }
          }

          換句話說,我改變了JVM的默認TimeZone,因此它沒有夏令時(DST)規則,所以你也不用擔心去調整它。

          后來J2SE 1.4發布了,于是我也升級了。但是意外的是:它的ItsInitializer類不能運行了。于是我立即再去調查。 發現了一個DateTest類的輸出(for J2SE 1.4.1_01 on Windows 98):

          Date = Tue May 06 05:31:03 IDT 2003
          Calendar = java.util.GregorianCalendar[time=1052188263870,areFieldsSet=true,areAllFieldsSet
          =true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Jerusalem",offset=7200000,
          dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone
          [id=Asia/Jerusalem,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,
          startMode=1,startMonth=3,startDay=1,startDayOfWeek=0,startTime=3600000,startTimeMode=0,
          endMode=1,endMonth=9,endDay=1,endDayOfWeek=0,endTime=3600000,endTimeMode=0]],
          firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2003,MONTH=4,WEEK_OF_YEAR=19,
          WEEK_OF_MONTH=2,DAY_OF_MONTH=6,DAY_OF_YEAR=126,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,
          HOUR=5,HOUR_OF_DAY=5,MINUTE=31,SECOND=3,MILLISECOND=870,ZONE_OFFSET=7200000,
          DST_OFFSET=3600000]

          你也看到了吧,J2SE 1.4中的TimeZone類的zone成員已經不在是SimpleTimeZone的一個實例了。取而代之的是sun.util.calendar.ZoneInfo類。因此,我需要改變它的Initializer來兼容J2SE 1.4平臺:

          import java.util.TimeZone;
          import java.util.SimpleTimeZone;

          public class ItsInitializer {
            private static boolean s_initialized = false;

            private ItsInitializer() {
            }

            public static synchronized void initialize() {
              if (!s_initialized) {
                // Modifies default time zone, disables Daylight Saving Time.
                TimeZone l_defaultTimeZone = TimeZone.getDefault();
                int l_rawOffset = l_defaultTimeZone.getRawOffset();
                String l_id = l_defaultTimeZone.getID();
                SimpleTimeZone l_simpleTimeZone = new SimpleTimeZone(l_rawOffset,
                                                                     l_id,
                                                                     0,
                                                                     0,
                                                                     0,
                                                                     0,
                                                                     0,
                                                                     0,
                                                                     0,
                                                                     0);
                TimeZone.setDefault(l_simpleTimeZone);
                s_initialized = true;
              }
            }
          }

          我創建了一個沒有DST規則的SimpleTimeZone實例,并將它指派為JVM的默認TimeZone. 第二個執行形式比第一個更好,因為它沒有為Calendar類的zone成員考慮一個實際的類。注意,這第二個版本是向下兼容的------它能在J2SE 1.3上很好的工作。沒有什么能比通過親身經歷來學習更有收獲,我想獲得更多的經驗,然后能完全解決這個問題。

          我認為,在夏令時(DTS)期間,我們總是會物理地去調整一下計算機的時間,因此我們從不必去調整DST了,這樣就可以使得JVM總是設置一個默認的沒有夏令時規則的time zone 。結果問題得以解決。

          于是我們高興地通過以上策略來開發我們的應用程序,所有事情都很順利了。沒有更多的日期和時間上的矛盾和差異。 當冬天來臨,我們將計算機時間重新調整回來。在程序中我們也沒有遇到任何日期和時間上的問題,這還要感謝ItsInitializer這個類。

          但是,后來發現,我犯了另一個錯,使我不得不又回到當初那種煩躁。

          一個無法預料的故障 
          冬天過了,夏天又一次來臨,自然的又進入了夏令時階段。我原本以為沒問題的,于是使用了上面的策略來解決。

          On the very day we moved to DST, I got timestamp discrepancies. What happened?

          今年,我沒有物理上去調整計算機的時間。我已經配置了我們的SUN服務器來使我們不需要物理地調整系統時鐘。date命令是一個Unix/Linux命令,用來顯示當前系統的日期和時間。date的Solaris版本使用timezone配置文件幫助自動調整DST的顯示。和Java的Calendar類的工作機制類似。因此,如果timezone配置文件被安裝了,你就不用物理地去調整系統時鐘了。我相信LINUX也可以這樣做。

          我們的Windows上運行的是Windows XP,我們也沒有物理地去調整系統時間。我們能在Windows XP配置時間區域。問題來了,對于DST,有時候會自動進行調整而有時候又不會調整,下面兩張圖顯示了這個:


          Figure 1. Time zone with automatic DST adjustment


          Figure 2. Time zone without automatic DST adjustment

           

           Translated by Willpower,2003.11.18

          posted on 2006-02-18 09:32 水煮三國 閱讀(422) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2006年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627281234
          567891011

          常用鏈接

          留言簿(4)

          隨筆分類(85)

          隨筆檔案(89)

          文章分類(14)

          文章檔案(42)

          收藏夾(37)

          java

          oracle

          Sybase

          搜索

          •  

          積分與排名

          • 積分 - 211126
          • 排名 - 265

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 漳平市| 多伦县| 滦平县| 常熟市| 东台市| 嘉义市| 安平县| 江城| 沁源县| 昌江| 许昌县| 汤阴县| 阜阳市| 鞍山市| 贵定县| 宿州市| 遵义市| 西丰县| 巫溪县| 荣成市| 深州市| 易门县| 葫芦岛市| 肥乡县| 龙游县| 綦江县| 卓资县| 虞城县| 长沙县| 元阳县| 正安县| 施甸县| 报价| 康平县| 黔西| 温宿县| 马尔康县| 灵台县| 杂多县| 开平市| 玉山县|