いまさら年齢計算式2007年09月24日 02時49分24秒

もう1ヶ月も前の話題じゃん

きっかけは、ここのあわせて読みたいでトップにきていたsshi.Continualさんの8/24の記事

リンク先のITproの記事によると、年齢を計算するのに

(今日の日付-誕生日)/10000の小数点以下切捨て。
でできるとのこと。なんとなくわかるような、ちょっと不思議なような。

記事を見てもらえばわかると思うが、この日本語による定義じゃ不十分で、日付部分の年・月・日を「YYYYMMDD」にしたものを整数として計算するというもの。

で、sshiさんの記事では「これ、簡単かぁ?」という感じでコメント欄が盛り上がっていたりしたのが約1月前。それをいまさら取り上げてみたり

で、何を思ったかというと

PHPやJavaScriptでこの手法を用いるのが適切かの議論はおいておいて、これSQLで使えるんちゃうかと。

たとえば顧客データなどの個人をあらわすデータでは、DB側に生年月日を入れておくけど、表示した際に年齢表示が必要な場合に、日付フォーマットが使用できるDBMSならこの式をそのまま使えるんちゃうかと。これは結構便利ではないかと。

たとえばSQLiteで

SELECT
	name,
	((strftime('%Y%m%d', 'now')-strftime('%Y%m%d', birthday))/10000) AS Age
FROM
	customer
とか、MySQLで
SELECT
	name,
	floor((date_format(CURRENT_TIMESTAMP, '%Y%m%d')-date_format(birthday, '%Y%m%d'))/10000) AS age
FROM
	customer
とか、Oracleで
SELECT
	name,
	floor((to_char(SYSDATE, 'YYYYMMDD')-to_char(birthday, 'YYYYMMDD'))/10000) AS age
FROM
	customer
とか。Oraは未確認だけど。あとSQLiteはロケール考慮しないので日付変わってから朝の9時までは1日ずれるけど。

と、ここまで書いてみて、案外記述が冗長なので、あんまり便利じゃない気がしてきたが、CASE文とか使わないし演算に使用する日付に対して何倍するだの何分の一にするだのって余計な数字が入り込まないので、「((YYYYMMDD)-(YYYYMMDD)/10000)の整数部分が年齢だ」ってどっかにコメントしておけば、まあ理解はしやすいのかな。

オマケ

コメント欄でJavaScriptでの記述例のURLが示されてたけど、個人的には年を10,000倍して、月をごにょごにょして、なんて計算するより

// birthdayは'YYYY-MM-DD'形式の文字列
function calcAge(birthday) {
	var today = new Date();
	today = [
		( "0000" + today.getFullYear() ).slice(-4),
		( ( "00" + today.getMonth() ) + 1 ).slice(-2),
		( "00" + today.getDate() ).slice(-2)
	].join("");
	return Math.floor( ( today - birthday.replace(/-/g, "") ) / 10000 );
}
くらいが見やすいかな。どうせ暗黙の型変換で文字列のまま演算できるし。つか、個人的にはformat.js使ってるので
return Math.floor( ( new Date().format("YYYYmmdd") - birthday.replace~
くらいにできるか。あるいはDateオブジェクト拡張しちまいそうだ。

蛇足

この記事書きながら、「この計算式、どっかで見たよなー」と思ってたら、あるSEのつぶやきさんの8/23付けのエントリでした。