annotate plugins/libcalendaring/lib/Sabre/VObject/DateTimeParser.php @ 43:771f6803cc4b default tip

somehow lost the correctly updated metadata so e.g. 'mail' package wasn't being imported
author Charlie Root
date Sun, 26 Jan 2025 13:13:49 -0500
parents 888e774ee983
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
1 <?php
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
2
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
3 namespace Sabre\VObject;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
4
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
5 /**
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
6 * DateTimeParser
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
7 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
8 * This class is responsible for parsing the several different date and time
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
9 * formats iCalendar and vCards have.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
10 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
11 * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
12 * @author Evert Pot (http://evertpot.com/)
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
13 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
14 */
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
15 class DateTimeParser {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
16
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
17 /**
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
18 * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
19 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
20 * Specifying a reference timezone is optional. It will only be used
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
21 * if the non-UTC format is used. The argument is used as a reference, the
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
22 * returned DateTime object will still be in the UTC timezone.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
23 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
24 * @param string $dt
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
25 * @param DateTimeZone $tz
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
26 * @return DateTime
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
27 */
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
28 static public function parseDateTime($dt,\DateTimeZone $tz = null) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
29
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
30 // Format is YYYYMMDD + "T" + hhmmss
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
31 $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
32
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
33 if (!$result) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
34 throw new \LogicException('The supplied iCalendar datetime value is incorrect: ' . $dt);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
35 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
36
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
37 if ($matches[7]==='Z' || is_null($tz)) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
38 $tz = new \DateTimeZone('UTC');
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
39 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
40 $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
41
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
42 // Still resetting the timezone, to normalize everything to UTC
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
43 $date->setTimeZone(new \DateTimeZone('UTC'));
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
44 return $date;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
45
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
46 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
47
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
48 /**
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
49 * Parses an iCalendar (rfc5545) formatted date and returns a DateTime object
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
50 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
51 * @param string $date
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
52 * @return DateTime
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
53 */
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
54 static public function parseDate($date) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
55
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
56 // Format is YYYYMMDD
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
57 $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
58
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
59 if (!$result) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
60 throw new \LogicException('The supplied iCalendar date value is incorrect: ' . $date);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
61 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
62
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
63 $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new \DateTimeZone('UTC'));
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
64 return $date;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
65
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
66 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
67
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
68 /**
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
69 * Parses an iCalendar (RFC5545) formatted duration value.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
70 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
71 * This method will either return a DateTimeInterval object, or a string
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
72 * suitable for strtotime or DateTime::modify.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
73 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
74 * @param string $duration
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
75 * @param bool $asString
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
76 * @return DateInterval|string
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
77 */
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
78 static public function parseDuration($duration, $asString = false) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
79
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
80 $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
81 if (!$result) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
82 throw new \LogicException('The supplied iCalendar duration value is incorrect: ' . $duration);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
83 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
84
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
85 if (!$asString) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
86 $invert = false;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
87 if ($matches['plusminus']==='-') {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
88 $invert = true;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
89 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
90
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
91
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
92 $parts = array(
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
93 'week',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
94 'day',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
95 'hour',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
96 'minute',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
97 'second',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
98 );
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
99 foreach($parts as $part) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
100 $matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
101 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
102
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
103
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
104 // We need to re-construct the $duration string, because weeks and
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
105 // days are not supported by DateInterval in the same string.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
106 $duration = 'P';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
107 $days = $matches['day'];
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
108 if ($matches['week']) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
109 $days+=$matches['week']*7;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
110 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
111 if ($days)
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
112 $duration.=$days . 'D';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
113
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
114 if ($matches['minute'] || $matches['second'] || $matches['hour']) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
115 $duration.='T';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
116
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
117 if ($matches['hour'])
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
118 $duration.=$matches['hour'].'H';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
119
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
120 if ($matches['minute'])
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
121 $duration.=$matches['minute'].'M';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
122
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
123 if ($matches['second'])
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
124 $duration.=$matches['second'].'S';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
125
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
126 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
127
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
128 if ($duration==='P') {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
129 $duration = 'PT0S';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
130 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
131 $iv = new \DateInterval($duration);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
132 if ($invert) $iv->invert = true;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
133
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
134 return $iv;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
135
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
136 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
137
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
138
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
139
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
140 $parts = array(
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
141 'week',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
142 'day',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
143 'hour',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
144 'minute',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
145 'second',
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
146 );
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
147
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
148 $newDur = '';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
149 foreach($parts as $part) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
150 if (isset($matches[$part]) && $matches[$part]) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
151 $newDur.=' '.$matches[$part] . ' ' . $part . 's';
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
152 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
153 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
154
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
155 $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
156 if ($newDur === '+') { $newDur = '+0 seconds'; };
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
157 return $newDur;
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
158
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
159 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
160
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
161 /**
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
162 * Parses either a Date or DateTime, or Duration value.
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
163 *
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
164 * @param string $date
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
165 * @param DateTimeZone|string $referenceTZ
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
166 * @return DateTime|DateInterval
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
167 */
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
168 static public function parse($date, $referenceTZ = null) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
169
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
170 if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
171 return self::parseDuration($date);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
172 } elseif (strlen($date)===8) {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
173 return self::parseDate($date);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
174 } else {
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
175 return self::parseDateTime($date, $referenceTZ);
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
176 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
177
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
178 }
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
179
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
180
888e774ee983 libcalendar plugin as distributed
Charlie Root
parents:
diff changeset
181 }