在工商業應用中,時間紀錄是系統中非常基本的東西,不過時間的表示方法就五花八門了。最近碰到一個需求是同一個時間欄位可能是 Y-m-d (ex. 2012-11-29)、quarter (Q4 2012)、month (Nov 2012),或是 year (2012),甚至是 TBA (to be announced)。
其中轉換成季 (quarter) 會用到一點點技巧,在此筆記如下:
<? $timestamp = mktime(0, 0, 0, 11, 29, 2012); echo ceil(date("m", $timestamp)/3); ?>
只要前面再加個 ‘Q’ 就是第幾季了。
在資料庫部份如何分辨客戶是儲存哪種型態,我的做法是多開一個 date_type 的欄位。
CREATE TABLE `calendar` ( `c_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `c_date` date NOT NULL, `c_date_type` char(1) NOT NULL DEFAULT 'd', PRIMARY KEY (`c_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
然後用以下 function 來轉換日期
function date_converter($date_type, $date){ $timestamp = strtotime($date); switch($date_type){ case 'd': return $date; break; case 'm': return date("Y-m-d", mktime(23, 59, 59, date('m', $timestamp) + 1, 0, date('Y', $timestamp))); break; case 'q': $the_quarter = ceil(date("m", $timestamp)/3); return date("Y-m-d", mktime(23, 59, 59, $the_quarter * 3 + 1, 0, date('Y', $timestamp))); break; case 'y': return date("Y-m-d", mktime(23, 59, 59, 12, 31, date('Y', $timestamp))); break; case 't': return '2099-12-31'; break; } }
最後將轉換後的日期與日期型態一份存入資料庫,讀取時根據型態做切換就可以了。
Updated:
後來又碰到一個需求,碰到資料庫日期相同時,例如季和月兩種日期都是記錄最後一天,Q1 與 March 在資料庫裡都是 3 / 31,排序的時候就有可能出現 Q1, March, Q1, March 交錯的現象。解決方法是在 SELECT … ORDER BY … 加個自訂排序,用前述的 date_type 來排列。
SELECT * FROM `calendar` ORDER BY `c_date` ASC, FIELD(`c_date_type`, `d`, `m`, `q`, `y`, `t`)
如此就可以避免不同型態日期交錯的問題。
Leave a Reply