コード

strftime代替機能

2010年3月9日

strftimeがサーバの設定によってさまざまな挙動をするので、Jeansでは代替機能を提供すればどうかというアイデアをいただきました

そこで、strftimeの代替関数を書いてみました。ポイントとしては、ロケールを指定するのではなく、言語ファイル(skins/jeans/language/japanese.phpなど)で表示する内容を設定するということです。とりあえずテスト用に書いたのが、次のコードです。よさそうならば、Jeansでは、strftimeクラスとして実装するのがきれいだと思います。

<?php

define('_JEANS_STRFTIME_XL','%y/%m/%d');
define('_JEANS_STRFTIME_CL','%Y年%b月%d日(%a) %H:%M:%S');
define('_JEANS_STRFTIME_AL','日|月|火|水|木|金|土');
define('_JEANS_STRFTIME_AH','日曜日|月曜日|火曜日|水曜日|木曜日|金曜日|土曜日');
define('_JEANS_STRFTIME_BL','1|2|3|4|5|6|7|8|9|10|11|12');
define('_JEANS_STRFTIME_BH','1月|2月|3月|4月|5月|6月|7月|8月|9月|10月|11月|12月');
define('_JEANS_STRFTIME_PL','午前|午後');
define('_JEANS_STRFTIME_PH','午前|午後');

echo @jeans_strftime('Today is %G-%m-%d %A(%a).')."\n";
echo @jeans_strftime('%B (%b)')."\n";
echo @jeans_strftime('%x')."\n";
echo @jeans_strftime('%c')."\n";

function jeans_strftime($format,$time=false){
	if ($time===false) $time=time();
	jeans_replace($time);
	$format=preg_replace_callback('/(%?)([a-zA-Z%])/','jeans_replace',$format);
	return date($format,$time);
}

function jeans_replace($m){
	static $time,$locale;
	if (!is_array($m)) {
		$time=$m;
		if (!isset($locale)) $locale=array(
			'c'=>_JEANS_STRFTIME_CL,
			'x'=>_JEANS_STRFTIME_XL,
			'a'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_AL)),
			'A'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_AH)),
			'b'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_BL)),
			'B'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_BH)),
			'p'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_PL)),
			'P'=>explode('|',preg_replace('/[a-zA-Z]/','\\\\$0',_JEANS_STRFTIME_PH)));
		return;
	}
	if ($m[1]!='%') return '\\'.$m[2];
	switch($m[2]){
		case 'a':             // Sun-Sat
			return $locale['a'][date('w',$time)];
		case 'A':             // Sunday-Saturday
			return $locale['A'][date('w',$time)];
		case 'd': return 'd'; // 01-31
		case 'e': return 'j'; // 1-31
		case 'j': return 'z'; // 001-366
		case 'u': return 'N'; //1-7
		case 'w': return 'w'; // 0-6
		case 'U':             // 1-53
			if (date('w',mktime(0, 0, 0, 1, 1, date('Y',$time)))==0) {
				if (date('w',$time)==0) return 'W';
				else return date('W',$time)-1;
			} else {
				if (date('w',$time)==0) return date('W',$time)+1;
				else return 'W';
			}
		case 'V': return 'W'; // 01-53
		case 'W': return 'W'; // 1-53
		case 'b':             // Jan-Dec
			return $locale['b'][date('n',$time)-1];
		case 'B':             // January-December
			return $locale['B'][date('n',$time)-1];
		case 'h': return 'M'; // Jan-Dec
		case 'm': return 'm'; // 01-12
		case 'C': return intval((date('Y',$time)-1)/100); // 19 or 20
		case 'g': return 'y'; // 00-99
		case 'G': return 'Y'; // 1970-2023
		case 'y': return 'y'; // 00-99
		case 'Y': return 'Y'; // 1970-2023
		case 'H': return 'H'; // 00-23
		case 'I': return 'h'; // 01-12
		case 'l': return preg_replace('/^0/',' ',date('h',$time)); // _1-12
		case 'M': return 'i'; // 00-59
		case 'p':             // AM or PM
			return date('A',$time)=='AM' ? $locale['p'][0]:$locale['p'][1];
		case 'P':             // am or pm
			return date('A',$time)=='AM' ? $locale['P'][0]:$locale['P'][1];
		case 'r': return 'h:i:s A'; // '%I:%M:%S %p'
		case 'R': return 'H:i'; // '%H:%M'
		case 'S': return 's'; // 00-59
		case 'T': return 'H:i:s'; // '%H:%M:%S'
		case 'X': return 'H:i:s';
		case 'z': return 'T'; // EST etc
		case 'Z': return 'O'; // -0500 etc
		case 'c': 'Y-m-d H:i:s'; // depends on locale
			return preg_replace_callback('/(%?)([a-zA-Z%])/','jeans_replace',$locale['c']);
		case 'D': return 'm/d/y'; // '%m/%d/%y'
		case 'F': return 'Y-m-d'; // '%y-%m-%d'
		case 's': return 'U'; // timestamp
		case 'x':             // depends on locale
			return preg_replace_callback('/(%?)([a-zA-Z%])/','jeans_replace',$locale['x']);
		case 'n': return "\n";
		case 't': return "\t";
		case '%': return '%';
		default : return '\\'.$m[2];
	}
}
実行結果
Today is 2010-03-08 月曜日(月).
3月 (3)
10/03/08
2010年3月08日(月) 15:32:59

ここに書いたコードはテスト用のコードで、Jeansが無くても機能します。12行目あたりを書き換えて、色々な表示の仕方を試してみてください。

要望をいただいた、『ゼロサプレスな書式指定』などは未だです。上記のコードをたたき台にして、改良していければと思います。

コメント

コメントはありません

コメント送信