まらんさんのチラ裏

その日暮らしのおじさん

CakePHPのdateTimeOptionTagを日本語化してみた

CakePHPの勉強中にdateTimeOptionTagを試してみたら月のセレクトボックスなんかが英語表記になっていて「つかえねー」とか思ったので日本語化した。
helperのhtml.phpに追記しても良いし、新規にhtmljp.phpとか作ってそこに書いても良いと思う。


まず「YYYY-MM-DD hh:mm am」とかいう表示からして気に入らないので、
「YYYY年MM月DD日 午前hh時mm分」のような表示に直す。

<?php
// 年月日日時のセレクトボックス生成
function dateTimeOptionTagJp($tagName, $dateFormat = 'DMY', $timeFormat = '12', $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
    $day      = null;
    $month    = null;
    $year     = null;
    $hour     = null;
    $min      = null;
    $meridian = null;

    if (empty($selected)) {
        $selected = $this->tagValue($tagName);
    }

    if (!empty($selected)) {

        if (is_int($selected)) {
            $selected = strftime('%Y-%m-%d %H:%M:%S', $selected);
        }

        $meridian = 'am';
        $pos = strpos($selected, '-');
        if ($pos !== false) {
            $date = explode('-', $selected);
            $days = explode(' ', $date[2]);
            $day = $days[0];
            $month = $date[1];
            $year = $date[0];
        } else {
            $days[1] = $selected;
        }

        if ($timeFormat != 'NONE' && !empty($timeFormat)) {
            $time = explode(':', $days[1]);
            $check = str_replace(':', '', $days[1]);

            if (($check > 115959) && $timeFormat == '12') {
                $time[0] = $time[0] - 12;
                $meridian = 'pm';
            } elseif ($time[0] > 12) {
                $meridian = 'pm';
            }

            $hour = $time[0];
            $min = $time[1];
        }
    }

    $elements = array('Day','Month','Year','Hour','Minute','Meridian');
    if (isset($selectAttr['id'])) {
        if (is_string($selectAttr['id'])) {
            // build out an array version
            foreach ($elements as $element) {
                $selectAttrName = 'select' . $element . 'Attr';
                ${$selectAttrName} = $selectAttr;
                ${$selectAttrName}['id'] = $selectAttr['id'] . $element;
            }
        } elseif (is_array($selectAttr['id'])) {
            // check for missing ones and build selectAttr for each element
            foreach ($elements as $element) {
                $selectAttrName = 'select' . $element . 'Attr';
                ${$selectAttrName} = $selectAttr;
                ${$selectAttrName}['id'] = $selectAttr['id'][strtolower($element)];
            }
        }
    } else {
        // build the selectAttrName with empty id's to pass
        foreach ($elements as $element) {
            $selectAttrName = 'select' . $element . 'Attr';
            ${$selectAttrName} = $selectAttr;
        }
    }

    switch($dateFormat) {
        case 'DMY': // so uses the new selex
            $opt = $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '' .
                $this->monthOptionTagJp($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty).'';
            break;
        case 'MDY':
            $opt = $this->monthOptionTagJp($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '' .
                $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty).'';
            break;
        case 'YMD':
            $opt = $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty) . '' .
                $this->monthOptionTagJp($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '' .
                $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty).'';
            break;
        case 'Y':
            $opt = $this->yearOptionTag($tagName, null, null, null, $selected, $selectYearAttr, $optionAttr, $showEmpty).'';
            break;
        case 'NONE':
        default:
            $opt = '';
            break;
    }

    switch($timeFormat) {
        case '24':
            $opt .= $this->hourOptionTag($tagName, null, true, $hour, $selectHourAttr, $optionAttr, $showEmpty) . '' .
                $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty).'';
            break;
        case '12':
            $opt .= $this->meridianOptionTagJp($tagName, null, $meridian, $selectMeridianAttr, $optionAttr, $showEmpty).' '.
                $this->hourOptionTag($tagName, null, false, $hour, $selectHourAttr, $optionAttr, $showEmpty) . '' .
                $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty) . '';
            break;
        case 'NONE':
        default:
            $opt .= '';
            break;
    }
    return $opt;
}
?>

なげえ。
次に、月が何故か英語表記になっていたので、普通に数字表記に直す。
なんで汎用性のある数字表記がデフォじゃないのか不思議。

<?php
// 月セレクトボックス生成
function monthOptionTagJp($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
    if (empty($selected) && ($this->tagValue($tagName))) {
        $selected = date('m', strtotime($this->tagValue($tagName)));
    }
    $monthValue = empty($selected) ? ($showEmpty ? NULL : date('m')) : $selected;
    $months = array('01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12');

    return $this->selectTag($tagName . "_month", $months, $monthValue, $selectAttr, $optionAttr, $showEmpty);
}
?>

最後に「AM」とか「PM」とかちょっとおしゃれな時計で表示されていそうな表記を
「午前」とか「午後」に直す。

<?php
// 午前・午後セレクトボックス生成
function meridianOptionTagJp($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
    if (empty($selected) && ($this->tagValue($tagName))) {
        $selected = date('a', strtotime($this->tagValue($tagName)));
    }
    $merValue = empty($selected) ? ($showEmpty ? NULL : date('a')) : $selected;
    $meridians = array('am' => '午前', 'pm' => '午後');

    $option = $this->selectTag($tagName . "_meridian", $meridians, $merValue, $selectAttr, $optionAttr, $showEmpty);
    return $option;
}
?>

凄く適当に勢いだけでやったのでバグを追加してしまった可能性も否めないがとりあえず誰か指摘してくれるのを待つ。