2007年8月25日 星期六

[程式設計] 排序/比較日期與時間的大小

  在 JiaYun 部落格看到這篇「判斷某月某日的大小介於關係」,嗯~又學到一招了。

  在 Delphi 中的日期與時間是採用 TDateTime 型別,也就是 double 實作的,整數的部分代表日期,小數的部分代表時間,要做日期與時間大小比對的話,基本上直接以關係運算子 (relation operator) 做運算就知道了。話雖如此,如果輸入的參數不是 TDateTime 型別的話,還得先利用 Delphi 內建的 DecodeDateTime 函式多做一手轉換;而這就會用到浮點運算,因此如果在大量運算時會多花點時間,雖然就今日的電腦來說都已內建了浮點運算處理器,但是如果在沒有浮點運算的機器上執行的話,就程式效能的觀點來說的話這樣的程式碼會較差一點。

  在這種情況下,採用 JiaYun 的做法自然是不二的選擇,也就是用以下的公式:

年 ╳ 10000 + 月 ╳ 100 + 日

  舉個例子來說的話,例如將 2007/12/31 與 2008/01/01 套入上述的公式,分別會得到 20071231 與 20080101 的整數,用關係運算子一比就馬上可得出兩者大小關係,相當方便,就效能來說的話也會比用上了浮點數或先轉換為字串再比對要快一點。

  如果是時間的話呢?如法泡製就是啦!
小時 ╳ 10000 + 分鐘 ╳ 100 + 秒
  要精確到毫秒的話,再乘上 1000 就是了:
小時 ╳ 10000000 + 分鐘 ╳ 100000 + 秒 ╳ 1000 + 毫秒    (還好不會爆掉)

  當然,除了效能上的好處之外,還有一點就是非常的直覺,一看就知道是多少,也可以直接轉成字串輸出。

1 則留言:

  1. 因為颱風,突然閒閒亂逛……
    如果真的強調效能的話,這還不是最快的方法,更快的方法是
    年*65536+月*256+日
    然後把乘換成shift就變成
    (年<<16)+(月<<8)+日
    然後+可以換成or
    (年<<16)|(月<<8)|日
    這樣就不必使用到加法與乘法了。
    什麼?你說這看起來一點也不直覺?只要能用人力把16進位轉成10進位就直覺了啦。這樣的好處除了可以比較大小外,要單獨取出年月日時會方便一些(不必用除法)。

    好吧,在這邊現(在某個其實根本不必這麼在意效能的的程式裡用的)方法也沒有什麼好高興的。

    回覆刪除

欲以匿名留言的讀者,為了便於分別您與他人,請在【發表留言的身分】欄位直接選用「名稱/網址」,然後僅輸入名稱不輸入網址即可。