Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

DateTypeのformatに"yyyy年MM月dd日"を指定しても"yyyy-MM-dd"扱いされる

FormTypeって、深いですね。。。
で、タイトルのとおりなんですが、DateTypeのformatに"yyyy年MM月dd日"を指定しても"yyyy-MM-dd"扱いされるんですね。

<?php
namespace Acme\CRUDBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ItemType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
                :
            ->add('printingOpenDate', 'date', 
                array(
                    'label' => '掲載開始日',
                    'required' => true,
                    'widget' => 'text',
                    'format' => 'yyyy年MM月dd日',
                ))
                :

これでフォームを表示すると

な感じになってしまいます。
調べてみると、Symfony\Component\Form\Extension\Core\Type\DateTypeクラスのbuildViewBottomUpメソッドでformatをパースしているんですが、最後の"([yMd]+)$"が原因のようです。

<?php
    public function buildViewBottomUp(FormView $view, FormInterface $form)
    {
                :
            // set right order with respect to locale (e.g.: de_DE=dd.MM.yy; en_US=M/d/yy)
            // lookup various formats at http://userguide.icu-project.org/formatparse/datetime
            if (preg_match('/^([yMd]+).+([yMd]+).+([yMd]+)$/', $pattern)) {
                $pattern = preg_replace(array('/y+/', '/M+/', '/d+/'), array('{{ year }}', '{{ month }}', '{{ day }}'), $pattern);
            } else {
                // default fallback
                $pattern = '{{ year }}-{{ month }}-{{ day }}';
            }
                :
        }
    }

で、

--- vendor/symfony/src/Symfony/Component/Form/Extension/Core/Type/DateType.php_ 2012-02-29 16:54:46.000000000 +0900
+++ vendor/symfony/src/Symfony/Component/Form/Extension/Core/Type/DateType.php  2012-02-29 17:14:11.000000000 +0900
@@ -139,7 +139,7 @@

             // set right order with respect to locale (e.g.: de_DE=dd.MM.yy; en_US=M/d/yy)
             // lookup various formats at http://userguide.icu-project.org/formatparse/datetime
-            if (preg_match('/^([yMd]+).+([yMd]+).+([yMd]+)$/', $pattern)) {
+            if (preg_match('/^([yMd]+).+([yMd]+).+([yMd]+)[^yMd]*$/', $pattern)) {
                 $pattern = preg_replace(array('/y+/', '/M+/', '/d+/'), array('{{ year }}', '{{ month }}', '{{ day }}'), $pattern);
             } else {
                 // default fallback

のように変更することで期待通り表示されるようになりました。

もっといい方法があればこっそり教えて下さい:-)

追記(2012/03/01 11:10)

id:rysterさんからトラックバックをもらいました。そちらの追記に書かれている方法がSymfonyのコアに手を入れることなく簡単です。