Недавно я узнал, что Zend_Date может использоваться в двух модах iso и php, причём iso используется по умолчанию.
При использовании валидатора Zend_Validate_Date в формах, мне больше нравится использовать php формат, к которому я привык за долгое время разработки web приложений.
Вот код, который создаёт элемент:
$subForm->addElement('text', 'start_date', array(
'filters' => array('StringTrim', 'StripTags'),
'required' => true,
'label' => 'Start date',
'validators' => array(
array('Date', true, array('format'=>'j F Y')),
),
));
Как вы уже заметили, я хочу чтобы дата была в формате "8 November 2010".
Этого добиться довольно таки просто, добавив код в Bootstrap.php:
function _initDateFormat()
{
Zend_Date::setOptions(array('format_type' => 'php'));
}
Обратите внимание на то, что это статический вызов, так что он распространяется на все инстанции Zend_Date.
Так же я обнаружил, что при использовании формата php многие выражения Zend_Date, такие как Zend_Date::MONTH не работают.
У нас есть несколько дорог, по которым мы можем пойти.
Менять формат отображения там, где это необходимо. Примерно так:
$currentOptions = Zend_Date::setOptions();
$currentFormatType = $currentOptions['format_type'];
Zend_Date::setOptions(array('format_type' => 'iso'));
// Теперь вы можете использовать Zend_Date::MONTH, ZEND_DATE::ISO и т.д.
// После этого вренуть всё как было
Zend_Date::setOptions(array('format_type' => $currentFormatType));
Так же мы можем перезаписать Zend_Validate_Date:
class App_Validate_Date extends Zend_Validate_Date
{
public function isValid ($value)
{
$currentOptions = Zend_Date::setOptions();
$currentFormatType = $currentOptions['format_type'];
Zend_Date::setOptions(array('format_type' => 'php'));
$valid = parent::isValid($value);
Zend_Date::setOptions(array('format_type' => $currentFormatType));
}
}
Так же у меня имеется несколько требований к валидации:
Определение пустого $value;
Формат Y-m-d так же должен проходить валидацию.
class App_Validate_Date extends Zend_Validate_Date
{
public function isValid ($value)
{
$this->_setValue($value);
if (empty($value)) {
return true;
}
$valid = $this->_testDateAgainstFormat($value, $this->getFormat());
if (!$valid) {
// проеряем на формат
$valid = $this->_testDateAgainstFormat($value, 'Y-m-d');
}
if ($valid) {
return true;
}
$this->_error(self::INVALID_DATE);
return false;
}
protected function _testDateAgainstFormat($value, $format)
{
$ts = strtotime($value);
if ($ts !== false) {
$testValue = date($format, $ts);
if ($testValue == $value) {
return true;
}
}
return false;
}
}
Этот код не будет работать если вы будете иметь дело с локализованными датами! Но вы всегда можете подстроить его под себя!