※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for 2008/12

日付整形手術  

2008/12/29 月曜日 12:55:26

・フォームから送信された日付をDBにINSERT、UPDATEできる形にするための整形
・DBからSELECTで引っ張ってきたDATETIME型の日付の整形

上記を例として日付の整形ってよく出食わします。
sprintf、substr、explode、正規表現を使う等、いろんなやり方があると思いますが…
自分が使っている方法をまとめてみます。

※例 DATETIME型の文字列を整形して表示

$time = '2008-07-10 21:02:23';
$data = sscanf($time, '%d-%d-%d %d:%d:%d');

sscanf()はprintf()の入力版で、文字列を指定したフォーマットに基づいて配列で抜き出します。
(フォーマットについてはprintf()のマニュアル参照)

$dataは下記のようになります

Array
(
    [0] => 2008
    [1] => 7
    [2] => 10
    [3] => 21
    [4] => 2
    [5] => 23
)

一発で変数に入れたい場合はlist()関数を使いましょう。

list($year, $month, $day, $hour, $minute, $second) =
	sscanf($time, '%d-%d-%d %d:%d:%d');
echo $year.'年'.$month.'月'.$day.'日 '.$hour.'時'.$minute.'分'.$second.'秒';

//【結果】2008年7月10日 21時2分23秒

こんな感じにすれば取り敢えず整形して表示できますが、一桁の月、日はゼロで穴埋めしたかったりする場合もあったりするので、ここは関数sprintf()を使って整形します。

echo sprintf('%d年%02d月%02d日 %02d時%02d分%02d秒',
	$year, $month, $day, $hour, $minute, $second);

//【結果】2008年07月10日 21時02分23秒

sprintf()の引数では配列を指定できませんが、vsprintf()を使うと配列を指定でき、

list($year, $month, $day, $hour, $minute, $second) =
	sscanf($time, '%d-%d-%d %d:%d:%d');
echo sprintf('%d年%02d月%02d日 %02d時%02d分%02d秒',
	$year, $month, $day, $hour, $minute, $second);

の二行を一行でやっつけちゃえます。

echo vsprintf('%d年%02d月%02d日 %02d時%02d分%02d秒',
	sscanf($time, '%d-%d-%d %d:%d:%d'));

関数やメソッドで用意しておくと使い回しできて良いかと思われます。

MoriMoriMoriMori MySQL, PHP, Tips, データベース

春分/秋分の日を打開する  

2008/12/29 月曜日 12:17:56

カレンダーを作る際、春分/秋分の日が変動して計算が面倒です。
そんな春分/秋分の求め方は以下。

function getSpringHolyday($year){
	if ($year <= 1947){
		$ret = false;
	}elseif ($year <= 1979){
		$ret = floor(20.8357 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}elseif ($year <= 2099){
		$ret = floor(20.8431 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}elseif ($year <= 2150){
		$ret = floor(21.851 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}else{
		$ret = false;
	}
	return $ret;
}

function getAutumHolyday($year){
	if ($year <= 1947){
		$ret = 99;
	}elseif ($year <= 1979){
		$ret = floor(23.2588 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}elseif ($year <= 2099){
		$ret = floor(23.2488 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}elseif ($year <= 2150){
		$ret = floor(24.2488 + (0.242194 * ($year - 1980)) -
			floor(($year - 1980) / 4));
	}else{
		$ret = 99;
	}
	return $ret;
}

20.8357とか、23.2588とか、0.242194とか、意味不明な数値が出てますが、
20.8357は、1980年の春分の日が、20日の20時14分4秒と発表されているので、そこから計算しているというわけです。23.2588も同様の考え方で・・。
0.242194は、1年365.242194日で扱われていたことから、差分として年数分計算してあげてます。
最後に、floor(($year - 1980) / 4)としているのは、閏年を考慮してます。
何分古いお話で、そんな感じで計算されてます。

下音タヌキ PHP

CASE式で値を変えて引っ張ってくる![MySQL]  

2008/12/16 火曜日 16:45:41

チョコボールです。
MySQLにてSELECT時に値の形を変えて引っ張ってくる方法。
僕はステータスが数字で管理されているようなDB(※例: 男性が「1」、女性が「2」等)をfetchしてきて表示する時等に使ってます。

取り敢えずSELECTで引っ張ってきてプログラム側で加工してやればいいんですが、CASE式を使えば加工の必要が無いので結構楽です。

下記のようなmemberテーブルがあったとします。

+----+------+--------+
| id | name | status |
+----+------+--------+
|  1 | 田中 |      0 |
|  2 | 辻川 |      1 |
|  3 | 鈴木 |      0 |
|  4 | 山本 |      1 |
|  5 | 西田 |      0 |
|  6 | 上村 |      2 |
|  7 | 星野 |      0 |
|  8 | 宮村 |      3 |
|  9 | 川田 |      1 |
| 10 | 山田 |      1 |
+----+------+--------+
ステータス
0 → 通常会員
1 → 有料会員
2 → 退会済会員

そのまま

SELECT * FROM member

としてfetchすると

Arrray
(
	[0] => Array
		(
			[id] => 1
			[name] => 田中
			[type] => 0
		)

	[1] => Array
		(
			[id] => 2
			[name] => 辻川
			[type] => 1
		)

	[2] => Array
		(
			[id] => 3
			[name] => 鈴木
			[type] => 0
		)
			・
			・
			・

のような感じで取得できますが、下記のようなSQLを組むことでプログラム側で加工無しに一発で引っ張ってくることが出来ます。

SELECT id, name,
	CASE
		WHEN type = '0' THEN '通常会員'
		WHEN type = '1' THEN '有料会員'
		WHEN type = '2' THEN '退会済会員'
		ELSE '不明'
	END type
FROM member
 Array
(
	[0] => Array
		(
			[id] => 1
			[name] => 田中
			[type] => 通常会員
		)

	[1] => Array
		(
			[id] => 2
			[name] => 辻川
			[type] => 有料会員
		)

	[2] => Array
		(
			[id] => 3
			[name] => 鈴木
			[type] => 通常会員
		)
			・
			・
			・

CASE式は他にもいろいろ使えるのでまた紹介します!

MoriMoriMoriMori MySQL, PHP

波ダッシュ(にょろ、波線)に気をつけましょう  

2008/12/4 木曜日 18:07:00

さて
文字コード周りで思いついたのでちょっと書いときます

波ダッシュ”〜”っていうのがあります。
にょろ とか 波線 とか言われてます。
Windowsだと普通に打つと”~”ですよね。
と、言ってもXPとそれより前では違うようですが・・・

色々問題があるようでSjisとUnicodeで変換かけると変わるとかあります。
と、いうか特定のエディタだと開けなかったりするみたいですね。
Shift_JISとUnicodeのマッピングが違うのが原因らしいですが、詳しいことはWikipedia見るといいと思います

で、PHP上で変換かける場合は

mb_convert_encoding('~', 'utf8', 'sjis-win');
mb_convert_encoding('〜','sjis-win','utf8');

ってな感じで”sjis-win”っていう拡張文字コード指定してあげれば求めている変換をしてくれると思います。
でもですね
特定のエディタで開けない(シェアのエディタ含む)場合があるので、複数人で触るようなソースに書くのはあんまりよろしくないのですよ

ってことで”〜”から”~”に変換するときは下の書き方の方がいいのかも

str_replace("xE3x80x9C",'~',$data);

たまーにMac使ってる人からデータもらうとそうなっている場合があるので、Macの方は注意した方がいいかもしれません。
携帯もSJISがメインなので。。。

“~”から”〜”に変換することはそうそうないと思いますので割愛

のびーにょ PHP, Tips, 携帯電話

表示で長い文字列を丸める!(自力篇)  

2008/12/2 火曜日 16:37:01

なんか便乗。
mb_strimwidth関数なんてシラネーって時に自力でやってました。
それ以前にPHPってここまで考慮されてるんだなーと、標準関数の多さにびっくらこきました。

で、自力でやってた感じは文字のバイト数見たりいろいろして変換。

function FN_chktext($text, $byte){
	// HTMLタグを取除く
	$text = strip_tags($text);

	// 文字変換
	mb_internal_encoding("SJIS");
	$text = mb_convert_kana($text, "RNASKH");

	// 文字数取得
	$t_num = mb_strlen($text);

	if ($t_num > $byte){
		$text = mb_substr($text, 0, $byte);
		$text .= "..";
		$text = mb_convert_kana($text, "s");
	}
	return $text;
}

たまーに中途半端なところで切れたりして文字化ける始末で、面倒だったりします。
でもって、たぶん普通にmb_strimwidth使った方が早いです、はい。

下音タヌキ 未分類