/**
  * Returns the value, in the format it should be encoded for json.
  *
  * This method must always return an array.
  *
  * @return array
  */
 public function getJsonValue()
 {
     $parts = DateTimeParser::parseVCardDateTime($this->getValue());
     $dateStr = $parts['year'] . '-' . $parts['month'] . '-' . $parts['date'] . 'T' . $parts['hour'] . ':' . $parts['minute'] . ':' . $parts['second'];
     // Timezone
     if (!is_null($parts['timezone'])) {
         $dateStr .= $parts['timezone'];
     }
     return array($dateStr);
 }
 /**
  * @dataProvider vcardDates
  * @expectedException \InvalidArgumentException
  */
 function testBadVCardDate()
 {
     DateTimeParser::parseVCardDateTime('1985---01');
 }
 /**
  * Validates the node for correctness.
  *
  * The following options are supported:
  *   Node::REPAIR - May attempt to automatically repair the problem.
  *
  * This method returns an array with detected problems.
  * Every element has the following properties:
  *
  *  * level - problem level.
  *  * message - A human-readable string describing the issue.
  *  * node - A reference to the problematic node.
  *
  * The level means:
  *   1 - The issue was repaired (only happens if REPAIR was turned on)
  *   2 - An inconsequential issue
  *   3 - A severe issue.
  *
  * @param int $options
  * @return array
  */
 public function validate($options = 0)
 {
     $messages = parent::validate($options);
     $value = $this->getValue();
     try {
         DateTimeParser::parseVCardDateTime($value);
     } catch (\InvalidArgumentException $e) {
         $messages[] = array('level' => 3, 'message' => 'The supplied value (' . $value . ') is not a correct DATE-AND-OR-TIME property', 'node' => $this);
     }
     return $messages;
 }
 /**
  * Parses the input data and returns a VCALENDAR.
  *
  * @return Component/VCalendar
  */
 function getResult()
 {
     $calendar = new VCalendar();
     foreach ($this->objects as $object) {
         // Skip if there is no BDAY property.
         if (!$object->select('BDAY')) {
             continue;
         }
         // We've seen clients (ez-vcard) putting "BDAY:" properties
         // without a value into vCards. If we come across those, we'll
         // skip them.
         if (empty($object->BDAY->getValue())) {
             continue;
         }
         // We're always converting to vCard 4.0 so we can rely on the
         // VCardConverter handling the X-APPLE-OMIT-YEAR property for us.
         $object = $object->convert(Document::VCARD40);
         // Skip if the card has no FN property.
         if (!isset($object->FN)) {
             continue;
         }
         // Skip if the BDAY property is not of the right type.
         if (!$object->BDAY instanceof Property\VCard\DateAndOrTime) {
             continue;
         }
         // Skip if we can't parse the BDAY value.
         try {
             $dateParts = DateTimeParser::parseVCardDateTime($object->BDAY->getValue());
         } catch (\InvalidArgumentException $e) {
             continue;
         }
         // Set a year if it's not set.
         $unknownYear = false;
         if (!$dateParts['year']) {
             $object->BDAY = self::DEFAULT_YEAR . '-' . $dateParts['month'] . '-' . $dateParts['date'];
             $unknownYear = true;
         }
         // Create event.
         $event = $calendar->add('VEVENT', ['SUMMARY' => sprintf($this->format, $object->FN->getValue()), 'DTSTART' => new \DateTime($object->BDAY->getValue()), 'RRULE' => 'FREQ=YEARLY', 'TRANSP' => 'TRANSPARENT']);
         // add VALUE=date
         $event->DTSTART['VALUE'] = 'DATE';
         // Add X-SABRE-BDAY property.
         if ($unknownYear) {
             $event->add('X-SABRE-BDAY', 'BDAY', ['X-SABRE-VCARD-UID' => $object->UID->getValue(), 'X-SABRE-VCARD-FN' => $object->FN->getValue(), 'X-SABRE-OMIT-YEAR' => self::DEFAULT_YEAR]);
         } else {
             $event->add('X-SABRE-BDAY', 'BDAY', ['X-SABRE-VCARD-UID' => $object->UID->getValue(), 'X-SABRE-VCARD-FN' => $object->FN->getValue()]);
         }
     }
     return $calendar;
 }
 /**
  * Returns the value, in the format it should be encoded for json.
  *
  * This method must always return an array.
  *
  * @return array
  */
 public function getJsonValue()
 {
     $parts = DateTimeParser::parseVCardDateTime($this->getValue());
     $dateStr = '';
     // Year
     if (!is_null($parts['year'])) {
         $dateStr .= $parts['year'];
         if (!is_null($parts['month'])) {
             // If a year and a month is set, we need to insert a separator
             // dash.
             $dateStr .= '-';
         }
     } else {
         if (!is_null($parts['month']) || !is_null($parts['date'])) {
             // Inserting two dashes
             $dateStr .= '--';
         }
     }
     // Month
     if (!is_null($parts['month'])) {
         $dateStr .= $parts['month'];
         if (isset($parts['date'])) {
             // If month and date are set, we need the separator dash.
             $dateStr .= '-';
         }
     } else {
         if (isset($parts['date'])) {
             // If the month is empty, and a date is set, we need a 'empty
             // dash'
             $dateStr .= '-';
         }
     }
     // Date
     if (!is_null($parts['date'])) {
         $dateStr .= $parts['date'];
     }
     // Early exit if we don't have a time string.
     if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) {
         return array($dateStr);
     }
     $dateStr .= 'T';
     // Hour
     if (!is_null($parts['hour'])) {
         $dateStr .= $parts['hour'];
         if (!is_null($parts['minute'])) {
             $dateStr .= ':';
         }
     } else {
         // We know either minute or second _must_ be set, so we insert a
         // dash for an empty value.
         $dateStr .= '-';
     }
     // Minute
     if (!is_null($parts['minute'])) {
         $dateStr .= $parts['minute'];
         if (!is_null($parts['second'])) {
             $dateStr .= ':';
         }
     } else {
         if (isset($parts['second'])) {
             // Dash for empty minute
             $dateStr .= '-';
         }
     }
     // Second
     if (!is_null($parts['second'])) {
         $dateStr .= $parts['second'];
     }
     // Timezone
     if (!is_null($parts['timezone'])) {
         $dateStr .= $parts['timezone'];
     }
     return array($dateStr);
 }