Skip to content

Commit

Permalink
Merge pull request #2164 from tractorcow/3.1-datetimefield-fixes
Browse files Browse the repository at this point in the history
BUG Fixed DateTimeField where time value was being parsed incorrectly.
  • Loading branch information
Sam Minnée committed Jul 7, 2013
2 parents ecf8f27 + feb03f5 commit 0173707
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
35 changes: 31 additions & 4 deletions forms/TimeField.php
Expand Up @@ -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.
Expand All @@ -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
Expand Down
32 changes: 32 additions & 0 deletions tests/forms/TimeFieldTest.php
Expand 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 0173707

Please sign in to comment.