Symfony Form の date/datetime フィールドを single_text ウィジェットとともに使った場合に 04-31 => 05-01 のような意図しない変換が発生する問題の発見と修正

3
マリオ @fumi_mario

Date(Time)Typeで(date_)widgetがsingle_textの場合checkdate()が掛からない。DateTimeToLocalizedStringTransformer::reverseTransform()内で掛けたいとこだけど。 #symfony2

2012-04-23 11:23:07
マリオ @fumi_mario

$options['widget'] === 'single_text' 以外の場合、DateTimeToArrayTransformer に行き、checkdate() が実装されているのだけどなあ。 #symfony2

2012-04-23 11:25:16
Hideyuki SHIMOOKA @shimooka

@fumi_mario checkdateに渡す年月日が別れて入力されない(single_textだとフォーマットを元に文字列を分解する必要がある)から面倒でやってらんね、とかですかねぇ。。。

2012-04-23 11:33:58
マリオ @fumi_mario

@shimooka そうなのかも知れませんね。一度 date_parse() してcheckdate() するコード 4 行程度を入れると期待する動作になったのですが、他と動作を合わせるためにも入れて欲しいですね。2/30 が 3/1 でそのまま動いちゃいますから。

2012-04-23 11:39:17
マリオ @fumi_mario

formatのオプションがあるからdate_parse()じゃ駄目だ。 RT @fumi_mario: @shimooka そうなのかも知れませんね。一度 date_parse() してcheckdate() するコード 4 行程度を入れると期待する動作になったのですが、他と動作

2012-04-23 11:50:27
Hideyuki SHIMOOKA @shimooka

@fumi_mario やるとすると、多分こんな感じですかね > http://t.co/mQHFALAV

2012-04-23 11:58:48
マリオ @fumi_mario

これは確かに面倒ですね。RT @shimooka: @fumi_mario やるとすると、多分こんな感じですかね > http://t.co/GQ7n2hvJ

2012-04-23 12:02:16
Atsuhiro Kubo @iteman

@rsky http://t.co/xsGsIg3M のデフォルト値についてマニュアルと異なるようですが、バグなのかドキュメントの間違いなのかわかりません。助けて。

2012-04-23 15:31:23
Ryusuke Sekiyama 🐈 @rsky

@iteman 行き着くところはICUのDateFormat::isLenient()→Calendar::isLenient()なのですが、ICU 3.4.1のソースコードを見た限りではCalendarのコンストラクタで fLenient(TRUE) と初期化されているので(続

2012-04-23 16:26:18
Ryusuke Sekiyama 🐈 @rsky

@rsky @iteman ドキュメントが誤っています。ICUの実装ではデフォルトで寛大(lenient)です

2012-04-23 16:34:03
Atsuhiro Kubo @iteman

@rsky ありがとうございます。すっきりしました。

2012-04-23 16:37:50
Atsuhiro Kubo @iteman

Symfony のフォームで誤った日付(2012/02/30)が正しい DataTime オブジェクト(2012/03/01)に変換される。 #symfony #php

2012-04-23 17:13:19
Atsuhiro Kubo @iteman

この挙動はフォームフィールドの形式が単一のテキストの場合のみ発生する。 #symfony #php

2012-04-23 17:13:35
Atsuhiro Kubo @iteman

IntlDateFormatter オブジェクトが変換に使われている。 #symfony #php

2012-04-23 17:14:18
Atsuhiro Kubo @iteman

誤った日付がエラーになるかどうかは IntlDateFormatter::isLenient() メソッドの値で決まる。 #symfony #php

2012-04-23 17:14:44
Atsuhiro Kubo @iteman

PHPマニュアルにはデフォルトのパーサは厳格なパーサ(isLenient() メソッドは false を返す)であると記述されている。 #symfony #php

2012-04-23 17:14:58
Atsuhiro Kubo @iteman

実際にはデフォルトのパーサは寛大なパーサ(isLenient() メソッドは true を返す)である。 #symfony #php

2012-04-23 17:15:09
Atsuhiro Kubo @iteman

大元の ICU は寛大なパーサ(isLenient() メソッドは true を返す)をデフォルトとする。 #symfony #php

2012-04-23 17:15:49
Atsuhiro Kubo @iteman

PHP マニュアルの記述が間違っている可能性がある。 #symfony #php

2012-04-23 17:16:13
Atsuhiro Kubo @iteman

Symfony の挙動が PHP マニュアルに従って厳格なパーサを意図している可能性がある。 #symfony #php

2012-04-23 17:16:24
Atsuhiro Kubo @iteman

Symfony のフォームについて setLenient(false) を呼び出すと、誤った日付がエラーになる。 #symfony #php

2012-04-23 17:16:34
Atsuhiro Kubo @iteman

@takagi 修正ありがとうございます。これで Symfony 側にも自信を持って提案できます。

2012-05-03 15:40:06
TAKAGI Masahiro @takagi

@iteman サンプルはちゃんとデフォルトTRUE前提で書いているし、どう見ても単純ミスでしょうね。

2012-05-03 15:46:48
Atsuhiro Kubo @iteman

@takagi そうですか。放置されていたということは、まだユーザが少ないんでしょうね。

2012-05-03 15:48:41
Atsuhiro Kubo @iteman

https://t.co/VHkKF04d こんなことでいいの?こうなったら徹底的に追求する。

2012-05-29 13:48:47