setValue($dt->format('Ymd\\THis')); $this->offsetUnset('VALUE'); $this->offsetUnset('TZID'); $this->offsetSet('VALUE','DATE-TIME'); break; case self::UTC : $dt->setTimeZone(new \DateTimeZone('UTC')); $this->setValue($dt->format('Ymd\\THis\\Z')); $this->offsetUnset('VALUE'); $this->offsetUnset('TZID'); $this->offsetSet('VALUE','DATE-TIME'); break; case self::LOCALTZ : $this->setValue($dt->format('Ymd\\THis')); $this->offsetUnset('VALUE'); $this->offsetUnset('TZID'); $this->offsetSet('VALUE','DATE-TIME'); $this->offsetSet('TZID', $dt->getTimeZone()->getName()); break; case self::DATE : $this->setValue($dt->format('Ymd')); $this->offsetUnset('VALUE'); $this->offsetUnset('TZID'); $this->offsetSet('VALUE','DATE'); break; default : throw new \InvalidArgumentException('You must pass a valid dateType constant'); } $this->dateTime = $dt; $this->dateType = $dateType; } /** * Returns the current DateTime value. * * If no value was set, this method returns null. * * @return \DateTime|null */ public function getDateTime() { if ($this->dateTime) return $this->dateTime; list( $this->dateType, $this->dateTime ) = self::parseData($this->value, $this); return $this->dateTime; } /** * Returns the type of Date format. * * This method returns one of the format constants. If no date was set, * this method will return null. * * @return int|null */ public function getDateType() { if ($this->dateType) return $this->dateType; list( $this->dateType, $this->dateTime, ) = self::parseData($this->value, $this); return $this->dateType; } /** * This method will return true, if the property had a date and a time, as * opposed to only a date. * * @return bool */ public function hasTime() { return $this->getDateType()!==self::DATE; } /** * Parses the internal data structure to figure out what the current date * and time is. * * The returned array contains two elements: * 1. A 'DateType' constant (as defined on this class), or null. * 2. A DateTime object (or null) * * @param string|null $propertyValue The string to parse (yymmdd or * ymmddThhmmss, etc..) * @param \OldSabre\VObject\Property|null $property The instance of the * property we're parsing. * @return array */ static public function parseData($propertyValue, VObject\Property $property = null) { if (is_null($propertyValue)) { return array(null, null); } $date = '(?P[1-2][0-9]{3})(?P[0-1][0-9])(?P[0-3][0-9])'; $time = '(?P[0-2][0-9])(?P[0-5][0-9])(?P[0-5][0-9])'; $regex = "/^$date(T$time(?PZ)?)?$/"; if (!preg_match($regex, $propertyValue, $matches)) { throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string'); } if (!isset($matches['hour'])) { // Date-only return array( self::DATE, new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')), ); } $dateStr = $matches['year'] .'-' . $matches['month'] . '-' . $matches['date'] . ' ' . $matches['hour'] . ':' . $matches['minute'] . ':' . $matches['second']; if (isset($matches['isutc'])) { $dt = new \DateTime($dateStr,new \DateTimeZone('UTC')); $dt->setTimeZone(new \DateTimeZone('UTC')); return array( self::UTC, $dt ); } // Finding the timezone. $tzid = $property['TZID']; if (!$tzid) { // This was a floating time string. This implies we use the // timezone from date_default_timezone_set / date.timezone ini // setting. return array( self::LOCAL, new \DateTime($dateStr) ); } // To look up the timezone, we must first find the VCALENDAR component. $root = $property; while($root->parent) { $root = $root->parent; } if ($root->name === 'VCALENDAR') { $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root); } else { $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid); } $dt = new \DateTime($dateStr, $tz); $dt->setTimeZone($tz); return array( self::LOCALTZ, $dt ); } }