symfony と 2038年問題
2010年4月20日(火) 19:10 JST
投稿者: 河口
PHPの日付/時間操作で使用されるUNIXタイムスタンプは、皆さんご存知のとおり、 で、symfony自体はどうかというと・・・ というか、symfony1.3から標準のORMとなったDoctrine自体がNG! このままでは、2038年以降の日付を扱うシステムを開発する際に問題になるので モデルを作成した際に作成されるBaseクラスは、sfDoctrineRecordという抽象クラスを継承します。 (1526行目) return strtotime($old) !== strtotime($new); 1./libフォルダ以下に、sfDoctrineRecordを継承した抽象クラスを作成し上記関数を
abstract class myDoctrineRecord extends sfDoctrineRecord
{
// override
protected function _isValueModified($type, $old, $new)
{
if ($new instanceof Doctrine_Expression) {
return true;
}
if ($type == 'timestamp' || $type == 'date')
{
// 2038年問題対応
// 5/8修正
//return date_create($old)->format(DATE_ISO8601)
// !== date_create($new)->format(DATE_ISO8601);
$old_val = null === $old ? false : date_create($old)->format(DATE_ISO8601);
public function configureDoctrine(Doctrine_Manager $manager)
{
// 追加したクラス名
$options = array('baseClassName'=>'myDoctrineRecord');
sfConfig::set('doctrine_model_builder_options', $options);
}
モデルの再作成すれば、Baseクラスの継承元が上記クラスに変更されます。
次に、widgetの対応をします。
(日付のwidgetにsfWidgetFormDateを利用している場合)
1./lib/以下に、sfWidgetFormDateを継承したクラスを作成し、render()を
そのままコピーしoverrideします。
class myWidgetFormDate extends sfWidgetFormDate
{
// override
public function render($name, $value = null, $attributes = array(), $errors = array())
{
~省略
(71行目)
// 2038年問題対応
// $value = (string) $value == (string) (integer) $value ?
// (integer) $value : strtotime($value);
// 5/8 修正
// $value = date_create($value);
$value = null === $value ? false : date_create($value);
~省略
(78行目)
// 2038年問題対応
// $value = array('year' => date('Y', $value),
// 'month' => date('n', $value),
// 'day' => date('j', $value));
$value = array('year' =>$value->format('Y'),
'month' => $value->format('n'),
'day' => $value->format('j'));
~省略
return strtr($this->getOption('format'), $date);
}
}
これで、2038年以降の日付も登録できるようになります。 ※ 5/8 追記 : DateTimeオブジェクトを作成し、処理する箇所にバグがあったので修正しました。 タグ: symfony |

