Java 企業(yè)應(yīng)用
          不要溫柔的走入那個(gè)良夜

            原來(lái)以為,求兩個(gè)時(shí)間之日期差應(yīng)該不是問(wèn)題,直到有一天...。 我曾經(jīng)輔導(dǎo)過(guò)的一位開(kāi)發(fā)員向我求教,我還不以為很難,嘗試用Calendar/GregorianCalendar類(lèi)來(lái)計(jì)算,看起來(lái)代碼太復(fù)雜,放棄。苦想半小時(shí),最后想出一句話,寫(xiě)出來(lái)在MSN上發(fā)給他。當(dāng)時(shí)的感覺(jué)路子很野,上不了臺(tái)面。這句話也是下面要介紹的簡(jiǎn)潔方法。
          再后來(lái),我的一位前同事發(fā)來(lái)郵件,說(shuō)起網(wǎng)上一大牛發(fā)布的blog,是一個(gè)牛人數(shù)落Java標(biāo)準(zhǔn)庫(kù)的,挺有意思。需求很簡(jiǎn)單:有兩個(gè)Date型的變量(a, b),如何計(jì)算兩者相隔的天數(shù)?你有簡(jiǎn)單的解決方案嗎?(據(jù)這個(gè)牛人說(shuō),還是很麻煩的哦)
          看了大牛的方法,暗地思忖:既然Java標(biāo)準(zhǔn)庫(kù)不能解決,我的方法不是很簡(jiǎn)單嗎?!我的底氣騰騰往上漲。

          ====
          我的方法:

          public long differ(Date date1, Date date2)
          {
          //return date1.getTime() / (24*60*60*1000) - date2.getTime() / (24*60*60*1000);
          return date2.getTime() / 86400000 - date1.getTime() / 86400000;  //用立即數(shù),減少乘法計(jì)算的開(kāi)銷(xiāo)
          }

          問(wèn)題分析:求日期差,重要的是時(shí)間對(duì)象的日期部分,與時(shí)分秒沒(méi)有關(guān)系。所以問(wèn)題的關(guān)鍵是過(guò)濾掉時(shí)分秒,保留日期部分。干的活象低通濾波器,濾掉高頻雜波,保留低頻信號(hào)。
          解決思路:一天的秒數(shù)是24*60*60*1000=86400000=Senconds。時(shí)間對(duì)象date1.getTime()是自1970年1月1日零點(diǎn)以來(lái)的秒數(shù),用它整除以Seconds,就得到自1970年1月1日以來(lái)的天數(shù)。注意這里用的是整除符號(hào),時(shí)分秒被過(guò)濾掉了。對(duì)date2也施行同樣的操作,得到date2的天數(shù)。date2的天數(shù)減去date1的天數(shù),所得結(jié)果就是日期差。
          舉例來(lái)說(shuō),用最簡(jiǎn)單的例子,假設(shè)date1等于1970年1月5日15點(diǎn)整,date2等于1970年1月6日14點(diǎn)整。date1整除以seconds的結(jié)果是4,date2整除以seconds的結(jié)果是5,date2與date1相差5-4=1天,與我們的預(yù)期相符。

          ====
          我的同事Kun給出了方法:獲取二者的milliseconds相減,然后/24/60/60。
          這個(gè)方法應(yīng)該是不正確的。因?yàn)槊霐?shù)相減,得到的是二者的時(shí)間差,并沒(méi)有濾掉時(shí)分秒。
          計(jì)算結(jié)果:用剛才的例子驗(yàn)算一下,date2.getTime() - date1.getTime() 等于相當(dāng)于23小時(shí)的秒數(shù),再整除以seconds,結(jié)果是0天,與預(yù)期的1天不相符。
          Kun的方法與正確方法的區(qū)別在于:先做減法,還是先做整除法。

          ====
          同事在網(wǎng)上找到的方法:

          SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
          java.util.Date date= myFormatter.parse("2003-05-1");
          java.util.Date mydate= myFormatter.parse("1899-12-30");
          long  day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
          out.println(day);

          結(jié)果應(yīng)該是正確的,它根本就沒(méi)有時(shí)分秒,有了時(shí)分秒與Kun的方法等價(jià)。不過(guò)用起來(lái)會(huì)很麻煩,因?yàn)橐鹊玫阶址娜掌冢拍苡盟?

          ====
          最后看看大牛的方法:
          大牛博客地址:http://blog.csdn.net/rmartin/archive/2006/12/22/1452867.aspx

          private int daysBetween(Date now, Date returnDate) {
              Calendar cNow = Calendar.getInstance();
              Calendar cReturnDate = Calendar.getInstance();
              cNow.setTime(now);
              cReturnDate.setTime(returnDate);
              setTimeToMidnight(cNow);
              setTimeToMidnight(cReturnDate);
          long todayMs = cNow.getTimeInMillis();
          long returnMs = cReturnDate.getTimeInMillis();
          long intervalMs = todayMs - returnMs;
          return millisecondsToDays(intervalMs);
            }

          private int millisecondsToDays(long intervalMs) {
          return (int) (intervalMs / (1000 * 86400));
            }

          private void setTimeToMidnight(Calendar calendar) {
              calendar.set(Calendar.HOUR_OF_DAY, 0);
              calendar.set(Calendar.MINUTE, 0);
              calendar.set(Calendar.SECOND, 0);
            }

          看起來(lái)很復(fù)雜吧,沒(méi)有求證過(guò),應(yīng)該是正確的吧!

          posted on 2012-04-16 18:15 cpegtop 閱讀(3419) 評(píng)論(1)  編輯  收藏
          Comments

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
           
          主站蜘蛛池模板: 鄢陵县| 东源县| 武定县| 鲁山县| 淅川县| 长治县| 枣庄市| 轮台县| 东乌珠穆沁旗| 诸暨市| 合山市| 同仁县| 三门峡市| 平罗县| 铁岭市| 镇平县| 余姚市| 辉南县| 恭城| 玛曲县| 榕江县| 梓潼县| 易门县| 漳平市| 刚察县| 丰顺县| 双城市| 咸阳市| 大余县| 罗城| 铜陵市| 台南县| 临湘市| 榆社县| 额敏县| 梅河口市| 滨州市| 永昌县| 永济市| 高邑县| 富裕县|