/**
  * Deconstructs the passed date value into all time units
  *
  * @param string|int|array|\DateTime|null $value Value to deconstruct.
  * @param array $options Options for conversion.
  * @return array
  */
 protected function _deconstructDate($value, $options)
 {
     if ($value === '' || $value === null) {
         return ['year' => '', 'month' => '', 'day' => '', 'hour' => '', 'minute' => '', 'second' => '', 'meridian' => ''];
     }
     try {
         if (is_string($value)) {
             $date = new IntlDateTime($value, null, 'persian');
         } elseif (is_bool($value)) {
             $date = new IntlDateTime(null, null, 'persian');
         } elseif (is_int($value)) {
             $date = new IntlDateTime('@' . $value, null, 'persian');
         } elseif (is_array($value)) {
             $dateArray = ['year' => '', 'month' => '', 'day' => '', 'hour' => '', 'minute' => '', 'second' => '', 'meridian' => 'pm'];
             $validDate = false;
             foreach ($dateArray as $key => $dateValue) {
                 $exists = isset($value[$key]);
                 if ($exists) {
                     $validDate = true;
                 }
                 if ($exists && $value[$key] !== '') {
                     $dateArray[$key] = str_pad($value[$key], 2, '0', STR_PAD_LEFT);
                 }
             }
             if ($validDate) {
                 if (!isset($dateArray['second'])) {
                     $dateArray['second'] = 0;
                 }
                 if (isset($value['meridian'])) {
                     $isAm = strtolower($dateArray['meridian']) === 'am';
                     $dateArray['hour'] = $isAm ? $dateArray['hour'] : $dateArray['hour'] + 12;
                 }
                 if (!empty($dateArray['minute']) && isset($options['minute']['interval'])) {
                     $dateArray['minute'] += $this->_adjustValue($dateArray['minute'], $options['minute']);
                 }
                 return $dateArray;
             }
             $date = new IntlDateTime(null, null, 'persian');
         } else {
             $date = clone $value;
         }
     } catch (\Exception $e) {
         $date = new IntlDateTime(null, null, 'persian');
     }
     if (isset($options['minute']['interval'])) {
         $change = $this->_adjustValue($date->format('mm'), $options['minute']);
         $date->modify($change > 0 ? "+{$change} minutes" : "{$change} minutes");
     }
     return ['year' => $date->format('Y'), 'month' => $date->format('MM'), 'day' => $date->format('dd'), 'hour' => $date->format('H'), 'minute' => $date->format('mm'), 'second' => $date->format('ss'), 'meridian' => $date->format('a')];
 }
 function testModify()
 {
     $date = new IntlDateTime('1388/04/01', 'Asia/Tehran', 'persian');
     $date->modify('+1 month');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1388/05/01 00:00:00');
     $date->set('1387/11/01');
     $date->modify('+1 year');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1388/11/01 00:00:00');
     $date->set('1387/11/01 03:45');
     $date->modify('next year');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1388/11/01 03:45:00');
     $date->set('1388/11/01');
     $date->modify('-12 months');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1387/11/01 00:00:00');
     $date->set('1386/12/01');
     $date->modify('-4days +2years +3hours');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1388/11/27 03:00:00');
     $date->set('1388/07/01');
     $date->modify('+1hour +30days -1month');
     $result = $date->format('yyyy/MM/dd HH:mm:ss');
     $this->assertEquals($result, '1388/07/01 01:00:00');
 }