他の多くの人と同じように、私もこれに苦労しました。グリッドをうまく表示することは問題ではありませんでしたが、ローカライズされた日時でのフィルタリングは問題でした!そこで、独自のフォーマッターを作成しsearch()
、モデルの関数で(検索パラメーターをに渡すときにcompare()
)使用しました。これは魅力のように機能します。ローカリゼーションの日付/日時フィールドでフィルタリングできるようになりました(オランダ語を使用)。
"30-12-2018" becomes "2018-12-30"
">30-12-2018" becomes ">2018-12-30"
"30-12-2018 23:59:49" becomes "2018-12-30 23:59:49"
">=30-12-2018 23:59:49" becomes ">=2018-12-30 23:59:49"
私のローカリゼーション:
// dateFormat['short'] = 'dd-MM-yyyy'
// timeFormat['medium'] = 'HH:mm:ss'
Yii::app()->format->datetimeFormat = strtr(Yii::app()->locale->dateTimeFormat,
array("{0}" => Yii::app()->locale->getTimeFormat('medium'),
"{1}" => Yii::app()->locale->getDateFormat('short')));
Yii::app()->format->dateFormat = 'short';
Yii::app()->format->timeFormat = 'medium';
私のCGridViewには、次の日時列が含まれています。
'mutation_date_time:dateTime'
そして(スニペット)いくつかの便利な機能を備えた私自身のフォーマッター:
class Formatter extends CLocalizedFormatter
{
public function formatWithoutSearchOperator($value)
{
// This snippet is taken from CDbCriteria->compare()
if(preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/',$value,$matches))
{
$value=$matches[2];
$op=$matches[1];
}
else
$op='';
return $value;
}
public function formatOnlySearchOperator($value)
{
// This snippet is taken from CDbCriteria->compare()
if(preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/',$value,$matches))
{
$value=$matches[2];
$op=$matches[1];
}
else
$op='';
return $op;
}
/*
* Format a localized datetime back to a database datetime (Y-m-d H:i:s).
* If a comparison operator is given, it is preserved. So strip it if you need to save the date in the database.
* If no time given, it's also not returned (MySQL database appends '00:00:00' as time to it upon saving).
* With this function the following localized datetimes just work like the stock datetime filters:
* - "30-12-2018" becomes "2018-12-30"
* - "30-12-2018 " becomes "1970-01-01" (note the extra space in input)
* - ">30-12-2018" becomes ">2018-12-30"
* - "30-12-2018 23:59:49" becomes "2018-12-30 23:59:49"
* - ">=30-12-2018 23:59:49" becomes ">=2018-12-30 23:59:49"
*
* For save() and afterFind() integration see:
* https://github.com/YetOpen/i18n-datetime-behavior
*/
public function formatToDatabaseDatetime($value)
{
// get the comparison operator from the string:
$comparator = $this->onlySearchOperator($value);
// get the datetime without the comparison operator:
$datetime = $this->withoutSearchOperator($value);
// parse the given datetime according to the locale format to a timestamp
$datetime_parsed = CDateTimeParser::parse(
$datetime,
strtr(
Yii::app()->locale->datetimeFormat,
array(
"{0}" => Yii::app()->locale->getTimeFormat(Yii::app()->format->timeFormat),
"{1}" => Yii::app()->locale->getDateFormat(Yii::app()->format->dateFormat)
)
)
);
// if its not a valid date AND time, check if it can be parsed to a date only:
if($datetime_parsed === false)
{
$date_parsed = CDateTimeParser::parse(
$datetime,
Yii::app()->locale->getDateFormat(Yii::app()->format->dateFormat)
);
}
// If no time part given, also output only the date
if($datetime_parsed===false)
{
$transformed = date(
'Y-m-d',
$date_parsed
);
}
else
{
$transformed = date(
'Y-m-d H:i:s',
$datetime_parsed
);
}
return $comparator . $transformed;
}
}
またsearch()
、CActiveRecordモデルの関数内で、以下を使用して、ローカライズされた日時をデータベース内のレコードと比較します。
$criteria->compare('mutation_date_time',Yii::app()->format->toDatabaseDateTime(trim($this->mutation_date_time)),true);
これは仕様によるものであることに注意してくださいtrim()
(関数の説明formatToDatabaseDateTime()を参照)。
正しいデータベース形式で直接フィルタリングすることとの大きな違い:無効な日付は「1970-01-01」に変換されます!
フィードバックに感謝します。私のコードが誰かに役立つことを心から願っています。