37 $result = preg_match(
'/^([0-9]{4})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/', $dt, $matches);
43 if ($matches[7] ===
'Z' || is_null(
$tz)) {
48 $date =
new DateTimeImmutable($matches[1] .
'-' . $matches[2] .
'-' . $matches[3] .
' ' . $matches[4] .
':' . $matches[5] .
':' . $matches[6],
$tz);
68 $result = preg_match(
'/^([0-9]{4})([0-1][0-9])([0-3][0-9])$/', $date, $matches);
101 $result = preg_match(
'/^(?<plusminus>\+|-)?P((?<week>\d+)W)?((?<day>\d+)D)?(T((?<hour>\d+)H)?((?<minute>\d+)M)?((?<second>\d+)S)?)?$/', $duration, $matches);
103 throw new InvalidDataException(
'The supplied iCalendar duration value is incorrect: ' . $duration);
110 if ($matches[
'plusminus'] ===
'-') {
122 foreach ($parts as $part) {
123 $matches[$part] = isset($matches[$part]) && $matches[$part] ? (int)$matches[$part] : 0;
129 $days = $matches[
'day'];
131 if ($matches[
'week']) {
132 $days += $matches[
'week'] * 7;
136 $duration .= $days .
'D';
139 if ($matches[
'minute'] || $matches[
'second'] || $matches[
'hour']) {
143 if ($matches[
'hour']) {
144 $duration .= $matches[
'hour'] .
'H';
147 if ($matches[
'minute']) {
148 $duration .= $matches[
'minute'] .
'M';
151 if ($matches[
'second']) {
152 $duration .= $matches[
'second'] .
'S';
157 if ($duration ===
'P') {
181 foreach ($parts as $part) {
182 if (isset($matches[$part]) && $matches[$part]) {
183 $newDur .=
' ' . $matches[$part] .
' ' . $part .
's';
187 $newDur = ($matches[
'plusminus'] ===
'-' ?
'-' :
'+') . trim($newDur);
189 if ($newDur ===
'+') {
190 $newDur =
'+0 seconds';
205 static function parse($date, $referenceTz = null) {
207 if ($date[0] ===
'P' || ($date[0] ===
'-' && $date[1] ===
'P')) {
208 return self::parseDuration($date);
209 } elseif (strlen($date) === 8) {
212 return self::parseDateTime($date, $referenceTz);
278 (?: (?<year> [0-9]{4}) (?: -)?| --) 284 (?<hour> [0-9]{2} | -) 285 (?<minute> [0-9]{2} | -)? 286 (?<second> [0-9]{2})? 288 (?: \.[0-9]{3})? # milliseconds 289 (?P<timezone> # timezone offset 291 Z | (?: \+|-)(?: [0-9]{4}) 298 if (!preg_match($regex, $date, $matches)) {
303 (?: (?<year> [0-9]{4}) - | -- ) 304 (?<month> [0-9]{2}) - 309 (?: (?<hour> [0-9]{2}) : | -) 310 (?: (?<minute> [0-9]{2}) : | -)? 311 (?<second> [0-9]{2})? 313 (?: \.[0-9]{3})? # milliseconds 314 (?P<timezone> # timezone offset 316 Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2}) 323 if (!preg_match($regex, $date, $matches)) {
339 foreach ($parts as $part) {
341 if (empty($matches[$part])) {
343 } elseif ($matches[$part] ===
'-' || $matches[$part] ===
'--') {
346 $result[$part] = $matches[$part];
400 (?<hour> [0-9]{2} | -) 401 (?<minute> [0-9]{2} | -)? 402 (?<second> [0-9]{2})? 404 (?: \.[0-9]{3})? # milliseconds 405 (?P<timezone> # timezone offset 407 Z | (?: \+|-)(?: [0-9]{4}) 413 if (!preg_match($regex, $date, $matches)) {
417 (?: (?<hour> [0-9]{2}) : | -) 418 (?: (?<minute> [0-9]{2}) : | -)? 419 (?<second> [0-9]{2})? 421 (?: \.[0-9]{3})? # milliseconds 422 (?P<timezone> # timezone offset 424 Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2}) 429 if (!preg_match($regex, $date, $matches)) {
442 foreach ($parts as $part) {
444 if (empty($matches[$part])) {
446 } elseif ($matches[$part] ===
'-') {
449 $result[$part] = $matches[$part];
512 $valueDate =
'/^(?J)(?:' .
513 '(?<year>\d{4})(?<month>\d\d)(?<date>\d\d)' .
514 '|(?<year>\d{4})-(?<month>\d\d)' .
515 '|--(?<month>\d\d)(?<date>\d\d)?' .
516 '|---(?<date>\d\d)' .
520 $valueTime =
'/^(?J)(?:' .
521 '((?<hour>\d\d)((?<minute>\d\d)(?<second>\d\d)?)?' .
522 '|-(?<minute>\d\d)(?<second>\d\d)?' .
523 '|--(?<second>\d\d))' .
524 '(?<timezone>(Z|[+\-]\d\d(\d\d)?))?' .
528 $valueDateTime =
'/^(?:' .
529 '((?<year0>\d{4})(?<month0>\d\d)(?<date0>\d\d)' .
530 '|--(?<month1>\d\d)(?<date1>\d\d)' .
531 '|---(?<date2>\d\d))' .
533 '(?<hour>\d\d)((?<minute>\d\d)(?<second>\d\d)?)?' .
534 '(?<timezone>(Z|[+\-]\d\d(\d\d?)))?' .
540 if (0 === preg_match($valueDate, $date, $matches)
541 && 0 === preg_match($valueDateTime, $date, $matches)
542 && 0 === preg_match($valueTime, $date, $matches)) {
557 $parts[
'date0'] = &$parts[
'date'];
558 $parts[
'date1'] = &$parts[
'date'];
559 $parts[
'date2'] = &$parts[
'date'];
560 $parts[
'month0'] = &$parts[
'month'];
561 $parts[
'month1'] = &$parts[
'month'];
562 $parts[
'year0'] = &$parts[
'year'];
564 foreach ($parts as $part => &$value) {
565 if (!empty($matches[$part])) {
566 $value = $matches[$part];
570 unset($parts[
'date0']);
571 unset($parts[
'date1']);
572 unset($parts[
'date2']);
573 unset($parts[
'month0']);
574 unset($parts[
'month1']);
575 unset($parts[
'year0']);
static parse($date, $referenceTz=null)
Parses either a Date or DateTime, or Duration value.
static parseVCardTime($date)
This method parses a vCard TIME value.
static parseDateTime($dt, DateTimeZone $tz=null)
Parses an iCalendar (rfc5545) formatted datetime and returns a DateTimeImmutable object.
static parseVCardDateAndOrTime($date)
This method parses a vCard date and or time value.
parseDate($dateString)
A collection of useful helpers for parsing or generating various HTTP headers.
static parseDate($date, DateTimeZone $tz=null)
Parses an iCalendar (rfc5545) formatted date and returns a DateTimeImmutable object.
static parseDuration($duration, $asString=false)
Parses an iCalendar (RFC5545) formatted duration value.
static parseVCardDateTime($date)
This method parses a vCard date and or time value.
This exception is thrown whenever an invalid value is found anywhere in a iCalendar or vCard object...