Tag: function

PHP: Finding the year quarter for a date

Posted by – November 29, 2012

在工商業應用中,時間紀錄是系統中非常基本的東西,不過時間的表示方法就五花八門了。最近碰到一個需求是同一個時間欄位可能是 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`)

如此就可以避免不同型態日期交錯的問題。

 

MySQL 字串連接 concat

Posted by – June 30, 2011

在 MySQL 資料庫中想產生一組獨一無二的 key,這樣可以做為比對的依據。打算直接在資料庫上操作新增欄位,至於 key 的產生是很直覺地想用 md5() 這個 function 來處理。但是因為要拿什麼資料來雜湊呢? 想說就用其他欄位加一加,再加上時間來湊。很直覺地寫下這樣的 query

SELECT md5( id + name + now() )

可惜這樣的結果會因為 id 是 int,而且 name 是 string 而產生非預期的結果。解決方法是把所有的欄位轉成 string 來處理,這時候需要 concat() 來組合字串。

SELECT md5( concat( id, name, now() ) )

這樣就可以得到正確的 md5 值了。

deaf03c84d18a56b70e0b7d6438ada3e

PHP mail function 如何避免亂碼?

Posted by – June 16, 2011

又是一個工作上碰到的問題,需要寫一個簡單的 email 發送功能。雖然是基本功能,不過常見的作法還是藉由 PHPMailer Library 來達成。不過這個案子因為寄信頻率很低,想說用 PHP 內建的 mail() 就可以處理了。但是人算不如天算,怎知 mail() 成功了,但是卻是一堆亂碼,標題、寄件人欄位都是亂碼..... 囧

經過一番 Google Search 的奮戰,找到一個很 tricky 的解決方法。將會出現亂碼的文字用以下方式處理....

"=?UTF-8?B?".base64_encode(" 會出現亂碼的文字 ")."?="

這樣用 GMAIL 收到信的時候就可以看到正常的文字了。

mail function 範例如下...

function sendMail($recipient){
    $subject = "=?UTF-8?B?".base64_encode("信件標題")."?=";
    $headers  = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=UTF-8\r\n";
    $headers .= "From: "."=?UTF-8?B?".base64_encode("寄件人 ")."?=";
    $headers .= "<sender@email.com>";
    $message  = '<p><font size="3" face="新細明體">信件內文</font></p> ';

    return mail($recipient, $subject, $message, $headers);
}

順便補充一下,為了送出 html 格式的郵件,必須在 header 中指定 Content-type: text/html 才行。

PHP 有 mb_encode_mimeheader 來為雙位元文字編碼,不過以此方式編碼的信件在 Gmail 中仍顯示亂碼,所以只好用比較 tricky 的方法來處理了。