/**
  * 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');
 }
 /**
  * Sets the internal value to ISO date format, based on either a database value in ISO date format,
  * or a form submssion in the user date format. Uses the individual date and time fields
  * to take care of the actual formatting and value conversion.
  *
  * Value setting happens *before* validation, so we have to set the value even if its not valid.
  *
  * Caution: Only converts user timezones when value is passed as array data (= form submission).
  * Weak indication, but unfortunately the framework doesn't support a distinction between
  * setting a value from the database, application logic, and user input.
  *
  * @param string|array $val String expects an ISO date format. Array notation with 'date' and 'time'
  *  keys can contain localized strings. If the 'dmyfields' option is used for {@link DateField},
  *  the 'date' value may contain array notation was well (see {@link DateField->setValue()}).
  * @return $this
  */
 public function setValue($val)
 {
     $locale = new Zend_Locale($this->locale);
     // If timezones are enabled, assume user data needs to be reverted to server timezone
     if ($this->getConfig('usertimezone')) {
         // Accept user input on timezone, but only when timezone support is enabled
         $userTz = is_array($val) && array_key_exists('timezone', $val) ? $val['timezone'] : null;
         if (!$userTz) {
             $userTz = $this->getConfig('usertimezone');
         }
         // fall back to defined timezone
     } else {
         $userTz = null;
     }
     if (empty($val)) {
         $this->value = null;
         $this->dateField->setValue(null);
         $this->timeField->setValue(null);
     } else {
         // Case 1: String setting from database, in ISO date format
         if (is_string($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $locale)) {
             $this->value = $val;
         } elseif (is_array($val) && array_key_exists('date', $val) && array_key_exists('time', $val)) {
             $dataTz = date_default_timezone_get();
             // If timezones are enabled, assume user data needs to be converted to server timezone
             if ($userTz) {
                 date_default_timezone_set($userTz);
             }
             // Uses sub-fields to temporarily write values and delegate dealing with their normalization,
             // actual sub-field value setting happens later
             $this->dateField->setValue($val['date']);
             $this->timeField->setValue($val['time']);
             if ($this->dateField->dataValue() && $this->timeField->dataValue()) {
                 $userValueObj = new Zend_Date(null, null, $locale);
                 $userValueObj->setDate($this->dateField->dataValue(), $this->dateField->getConfig('datavalueformat'));
                 $userValueObj->setTime($this->timeField->dataValue(), $this->timeField->getConfig('datavalueformat'));
                 if ($userTz) {
                     $userValueObj->setTimezone($dataTz);
                 }
                 $this->value = $userValueObj->get($this->getConfig('datavalueformat'), $locale);
                 unset($userValueObj);
             } else {
                 // Validation happens later, so set the raw string in case Zend_Date doesn't accept it
                 $this->value = trim(sprintf($this->getConfig('datetimeorder'), $val['date'], $val['time']));
             }
             if ($userTz) {
                 date_default_timezone_set($dataTz);
             }
         } else {
             $this->dateField->setValue($val);
             if (is_string($val)) {
                 $this->timeField->setValue($val);
             }
             $this->value = $val;
         }
         // view settings (dates might differ from $this->value based on user timezone settings)
         if (Zend_Date::isDate($this->value, $this->getConfig('datavalueformat'), $locale)) {
             $valueObj = new Zend_Date($this->value, $this->getConfig('datavalueformat'), $locale);
             if ($userTz) {
                 $valueObj->setTimezone($userTz);
             }
             // Set view values in sub-fields
             if ($this->dateField->getConfig('dmyfields')) {
                 $this->dateField->setValue($valueObj->toArray());
             } else {
                 $this->dateField->setValue($valueObj->get($this->dateField->getConfig('dateformat'), $locale));
             }
             $this->timeField->setValue($valueObj->get($this->timeField->getConfig('timeformat'), $locale));
         }
     }
     return $this;
 }