BUG Fixed issue where time value was being parsed incorrectly in some locales

This commit is contained in:
Damian Mooyman 2013-06-28 16:45:33 +12:00
parent 973a23fac8
commit feb03f5443
2 changed files with 63 additions and 4 deletions

View File

@ -77,12 +77,40 @@ class TimeField extends TextField {
return 'time text'; return 'time text';
} }
/**
* Parses a time into a Zend_Date object
*
* @param string $value Raw value
* @param string $format Format string to check against
* @param string $locale Optional locale to parse against
* @param boolean $exactMatch Flag indicating that the date must be in this
* exact format, and is unchanged after being parsed and written out
*
* @return Zend_Date Returns the Zend_Date, or null if not in the specified format
*/
protected function parseTime($value, $format, $locale = null, $exactMatch = false) {
// Check if the date is in the correct format
if(!Zend_Date::isDate($value, $format)) return null;
// Parse the value
$valueObject = new Zend_Date($value, $format, $locale);
// For exact matches, ensure the value preserves formatting after conversion
if($exactMatch && ($value !== $valueObject->get($format))) {
return null;
} else {
return $valueObject;
}
}
/** /**
* Sets the internal value to ISO date format. * Sets the internal value to ISO date format.
* *
* @param String|Array $val * @param String|Array $val
*/ */
public function setValue($val) { public function setValue($val) {
// Fuzzy matching through strtotime() to support a wider range of times, // Fuzzy matching through strtotime() to support a wider range of times,
// e.g. 11am. This means that validate() might not fire. // e.g. 11am. This means that validate() might not fire.
// Note: Time formats are assumed to be less ambiguous than dates across locales. // Note: Time formats are assumed to be less ambiguous than dates across locales.
@ -99,13 +127,12 @@ class TimeField extends TextField {
$this->valueObj = null; $this->valueObj = null;
} }
// load ISO time from database (usually through Form->loadDataForm()) // load ISO time from database (usually through Form->loadDataForm())
else if(Zend_Date::isDate($val, $this->getConfig('datavalueformat'))) { // Requires exact format to prevent false positives from locale specific times
$this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat')); else if($this->valueObj = $this->parseTime($val, $this->getConfig('datavalueformat'), null, true)) {
$this->value = $this->valueObj->get($this->getConfig('timeformat')); $this->value = $this->valueObj->get($this->getConfig('timeformat'));
} }
// Set in current locale (as string) // Set in current locale (as string)
else if(Zend_Date::isDate($val, $this->getConfig('timeformat'), $this->locale)) { else if($this->valueObj = $this->parseTime($val, $this->getConfig('timeformat'), $this->locale)) {
$this->valueObj = new Zend_Date($val, $this->getConfig('timeformat'), $this->locale);
$this->value = $this->valueObj->get($this->getConfig('timeformat')); $this->value = $this->valueObj->get($this->getConfig('timeformat'));
} }
// Fallback: Set incorrect value so validate() can pick it up // Fallback: Set incorrect value so validate() can pick it up

View File

@ -100,4 +100,36 @@ class TimeFieldTest extends SapphireTest {
$field->setValue(''); $field->setValue('');
$this->assertEquals($field->dataValue(), ''); $this->assertEquals($field->dataValue(), '');
} }
/**
* Test that AM/PM is preserved correctly in various situations
*/
public function testPreserveAMPM() {
// Test with timeformat that includes hour
// Check pm
$f = new TimeField('Time', 'Time');
$f->setConfig('timeformat', 'h:mm:ss a');
$f->setValue('3:59 pm');
$this->assertEquals($f->dataValue(), '15:59:00');
// Check am
$f = new TimeField('Time', 'Time');
$f->setConfig('timeformat', 'h:mm:ss a');
$f->setValue('3:59 am');
$this->assertEquals($f->dataValue(), '03:59:00');
// Check with ISO date/time
$f = new TimeField('Time', 'Time');
$f->setConfig('timeformat', 'h:mm:ss a');
$f->setValue('15:59:00');
$this->assertEquals($f->dataValue(), '15:59:00');
// ISO am
$f = new TimeField('Time', 'Time');
$f->setConfig('timeformat', 'h:mm:ss a');
$f->setValue('03:59:00');
$this->assertEquals($f->dataValue(), '03:59:00');
}
} }