PHPで元号年月日入力(プルダウン方式)

(1/1)
PHP でプルダウンメニューを使って元号(明治、大正‥‥)年月日を入力するフォームを作る。元号の切り替わり(例:昭和 64 年 1 月 7 日=平成元年 1 月 7 日)に注意し、存在しない年月日は入力できないようにする。また、日数は大の月と小の月によって変わるようにし、とくに閏年の 2 月の入力に気をつける。

サンプル・プログラム

プログラムを実行する

ダウンロード(PHP4/5共用)

元号の開始と終了

0125: /**
0126:  * 指定した元号の開始年月日を返す
0127:  * @param int $gengo  元号(UTF-8)
0128:  * @return array(元号,年,月,日)
0129: */
0130: function getGengoHead($gengo) {
0131:     static $tbl = array('明治'=>'0010125', '大正'=>'0010730', '昭和'=>'0011225', '平成'=>'0010107');
0132:     return isset($tbl[$gengo]) ? array($gengosubstr($tbl[$gengo], 0, 3) + 0, substr($tbl[$gengo], 3, 2) + 0, substr($tbl[$gengo], 5, 2) + 0) : FALSE;
0133: }
0134: 
0135: /**
0136:  * 指定した元号の終了年月日を返す
0137:  * @param int $gengo  元号(UTF-8)
0138:  * @return array(元号,年,月,日)/FALSE
0139: */
0140: function getGengoTail($gengo) {
0141:     static $tbl = array('明治'=>'0450730', '大正'=>'0151225', '昭和'=>'0640107', '平成'=>'0991231');
0142:     return isset($tbl[$gengo]) ? array($gengosubstr($tbl[$gengo], 0, 3) + 0, substr($tbl[$gengo], 3, 2) + 0, substr($tbl[$gengo], 5, 2) + 0) : FALSE;
0143: }
0144: 
0145: /**
0146:  * 元号年を西暦年に変換する
0147:  * @param string $gengo 元号
0148:  * @param int    $year 元号年
0149:  * @return int 西暦年/FALSE
0150: */
0151: function gengo2year($gengo$year) {
0152:     static $tbl = array('明治'=>1868, '大正'=>1911, '昭和'=>1925, '平成'=>1988);
0153:     return isset($tbl[$gengo]) ? $tbl[$gengo] + $year : FALSE;
0154: }

プログラムの部品は、いままで作ってきた「PHP で日本語対応 date を作る」「PHP で年月日を入力」の寄せ集めである。あらたに作るのは、元号の切り替わり(例:昭和 64 年 1 月 7 日=平成元年 1 月 7 日)に注意して年月日のプルダウンを制御する部分である。
space
まず、元号の開始と終了を求める関数と、元号を西暦年に変換する関数を用意する。
space

元号年月日をプルダウンメニューにする

0156: /**
0157:  * HTML BODYを作成する
0158:  * @param bool $mode TRUE=プルダウン/FALSE=表示
0159:  * @param int $year,$month,$day 年,月,日
0160:  * @return string HTML BODY
0161: */
0162: function makeCommonBody($mode$gengo$year$month$day) {
0163:     global $MySelf;
0164:     static $gtbl = array('明治', '大正', '昭和', '平成');
0165: 
0166:     $yyyy = gengo2year($gengo$year);       //西暦年
0167: 
0168:     list($gg$y0$m0$d0) = getGengoHead($gengo);
0169:     list($gg$y1$m1$d1) = getGengoTail($gengo);
0170:     if ($year != $y0 && $year != $y1) {
0171:         $m0 = 1; $m1 = 12;
0172:         $d0 = 1; $d1 = getDaysInMonth($yyyy$month);
0173:     } else if ($year == $y0) {
0174:         $m1 = 12;
0175:         $d1 = getDaysInMonth($yyyy$month);
0176:         if ($month != $m0)       $d0 = 1;
0177:     } else if ($year == $y1) {
0178:         $m0 = 1;
0179:         $d0 = 1;
0180:         if ($month != $m1)       $d1 = getDaysInMonth($yyyy$month);
0181:     }
0182: 
0183:     $outstr = '';
0184: //--プルダウンメニュー
0185:     if ($mode) {
0186:         $name = 'exec';
0187: //--元号
0188:     $outstr .=<<< EOD
0189: <select name="gengo" onChange="submit();">
0190: 
0191: EOD;
0192:     foreach ($gtbl as $val) {
0193:         $selected = ($val == $gengo) ? 'selected' : '';
0194:         $outstr .=<<< EOD
0195: <option value="{$val}" {$selected}>{$val}</option>
0196: 
0197: EOD;
0198:     }
0199:     $outstr .=<<< EOD
0200: </select> 
0201: 
0202: EOD;
0203: 
0204: //--年
0205:     $outstr .=<<< EOD
0206: <select name="year" onChange="submit();">
0207: 
0208: EOD;
0209:     for ($y = $y0$y <= $y1$y++) {
0210:         $selected = ($y == $year) ? 'selected' : '';
0211:         $outstr .=<<< EOD
0212: <option value="{$y}" {$selected}>{$y}</option>
0213: 
0214: EOD;
0215:     }
0216:     $outstr .=<<< EOD
0217: </select>年
0218: 
0219: EOD;
0220: 
0221: //--月
0222:     $outstr .=<<< EOD
0223: <select name="month" onChange="submit();">
0224: 
0225: EOD;
0226:     for ($m = $m0$m <= $m1$m++) {
0227:         $selected = ($m == $month) ? 'selected' : '';
0228:         $outstr .=<<< EOD
0229: <option value="{$m}" {$selected}>{$m}</option>
0230: 
0231: EOD;
0232:     }
0233:     $outstr .=<<< EOD
0234: </select>月
0235: 
0236: EOD;
0237: 
0238: //--日
0239:     $outstr .=<<< EOD
0240: <select name="day" onChange="submit();">
0241: 
0242: EOD;
0243:     for ($d = $d0$d <= $d1$d++) {
0244:         $selected = ($d == $day) ? 'selected' : '';
0245:         $outstr .=<<< EOD
0246: <option value="{$d}" {$selected}>{$d}</option>
0247: 
0248: EOD;
0249:     }

プルダウンメニューは、元号(gengo、)年(year)、月(month)、日(day)を別々のタグにする。
space
ある元号(gengo)の最初の年(元年、1 年)または最終の年以外であれば、その年の開始月($m0)は 1 月、終了月($m1)は 12 月、開始日($d0)は 1 日、終了日はユーザー関数 getDayInMonth の戻り値である。‥‥(A)
space
最初の年であれば、終了月、終了日は(A)と同じだが、開始月はユーザー関数 getGengoHead の戻り値である。
space
その元号の最終の年であれば、開始月、開始日は(A)と同じだが、終了月はユーザー関数 getGengoTail の戻り値である。
space
このプルダウンメニューが変化したら、JavaScript の onChange イベントで submit 駆動し、form 内容を送信するようにしている。これは元号(gengo)、年(year)、月(month)の場合も同様で、これを行うことで、元号・年・月・日を変更した際に再計算を行う。
space
ただし、いちいちサーバサイドで計算させることはサーバに負荷がかかるので、この処理は、本来はクライアントサイドで JavaScript で行わせるのが良いだろう。JavaScript による処理については、いずれどこかで紹介したい。
space

参考サイト

参考書籍

(この項おわり)
header