Permalink
Browse files

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

… locales
  • Loading branch information...
1 parent 973a23f commit feb03f5443329252eb5d975ed925b7ab4f1b5970 @tractorcow tractorcow committed Jun 28, 2013
Showing with 63 additions and 4 deletions.
  1. +31 −4 forms/TimeField.php
  2. +32 −0 tests/forms/TimeFieldTest.php
View
@@ -76,13 +76,41 @@ public function Field($properties = array()) {
public function Type() {
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.
*
* @param String|Array $val
*/
public function setValue($val) {
+
// Fuzzy matching through strtotime() to support a wider range of times,
// e.g. 11am. This means that validate() might not fire.
// Note: Time formats are assumed to be less ambiguous than dates across locales.
@@ -99,13 +127,12 @@ public function setValue($val) {
$this->valueObj = null;
}
// load ISO time from database (usually through Form->loadDataForm())
- else if(Zend_Date::isDate($val, $this->getConfig('datavalueformat'))) {
- $this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'));
+ // Requires exact format to prevent false positives from locale specific times
+ else if($this->valueObj = $this->parseTime($val, $this->getConfig('datavalueformat'), null, true)) {
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
}
// Set in current locale (as string)
- else if(Zend_Date::isDate($val, $this->getConfig('timeformat'), $this->locale)) {
- $this->valueObj = new Zend_Date($val, $this->getConfig('timeformat'), $this->locale);
+ else if($this->valueObj = $this->parseTime($val, $this->getConfig('timeformat'), $this->locale)) {
$this->value = $this->valueObj->get($this->getConfig('timeformat'));
}
// Fallback: Set incorrect value so validate() can pick it up
@@ -100,4 +100,36 @@ public function testOverrideWithNull() {
$field->setValue('');
$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');
+ }
}

0 comments on commit feb03f5

Please sign in to comment.