ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
DateAndOrTime.php
Go to the documentation of this file.
1<?php
2
4
5use DateTime;
6use DateTimeImmutable;
7use DateTimeInterface;
11use Sabre\Xml;
12
22class DateAndOrTime extends Property {
23
29 public $delimiter = null;
30
39 function getValueType() {
40
41 return 'DATE-AND-OR-TIME';
42
43 }
44
54 function setParts(array $parts) {
55
56 if (count($parts) > 1) {
57 throw new \InvalidArgumentException('Only one value allowed');
58 }
59 if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) {
60 $this->setDateTime($parts[0]);
61 } else {
62 parent::setParts($parts);
63 }
64
65 }
66
78 function setValue($value) {
79
80 if ($value instanceof DateTimeInterface) {
81 $this->setDateTime($value);
82 } else {
83 parent::setValue($value);
84 }
85
86 }
87
95 function setDateTime(DateTimeInterface $dt) {
96
97 $tz = $dt->getTimeZone();
98 $isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z']);
99
100 if ($isUtc) {
101 $value = $dt->format('Ymd\\THis\\Z');
102 } else {
103 // Calculating the offset.
104 $value = $dt->format('Ymd\\THisO');
105 }
106
107 $this->value = $value;
108
109 }
110
127 function getDateTime() {
128
129 $now = new DateTime();
130
131 $tzFormat = $now->getTimezone()->getOffset($now) === 0 ? '\\Z' : 'O';
132 $nowParts = DateTimeParser::parseVCardDateTime($now->format('Ymd\\This' . $tzFormat));
133
134 $dateParts = DateTimeParser::parseVCardDateTime($this->getValue());
135
136 // This sets all the missing parts to the current date/time.
137 // So if the year was missing for a birthday, we're making it 'this
138 // year'.
139 foreach ($dateParts as $k => $v) {
140 if (is_null($v)) {
141 $dateParts[$k] = $nowParts[$k];
142 }
143 }
144 return new DateTimeImmutable("$dateParts[year]-$dateParts[month]-$dateParts[date] $dateParts[hour]:$dateParts[minute]:$dateParts[second] $dateParts[timezone]");
145
146 }
147
155 function getJsonValue() {
156
158
159 $dateStr = '';
160
161 // Year
162 if (!is_null($parts['year'])) {
163
164 $dateStr .= $parts['year'];
165
166 if (!is_null($parts['month'])) {
167 // If a year and a month is set, we need to insert a separator
168 // dash.
169 $dateStr .= '-';
170 }
171
172 } else {
173
174 if (!is_null($parts['month']) || !is_null($parts['date'])) {
175 // Inserting two dashes
176 $dateStr .= '--';
177 }
178
179 }
180
181 // Month
182 if (!is_null($parts['month'])) {
183
184 $dateStr .= $parts['month'];
185
186 if (isset($parts['date'])) {
187 // If month and date are set, we need the separator dash.
188 $dateStr .= '-';
189 }
190
191 } elseif (isset($parts['date'])) {
192 // If the month is empty, and a date is set, we need a 'empty
193 // dash'
194 $dateStr .= '-';
195 }
196
197 // Date
198 if (!is_null($parts['date'])) {
199 $dateStr .= $parts['date'];
200 }
201
202
203 // Early exit if we don't have a time string.
204 if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) {
205 return [$dateStr];
206 }
207
208 $dateStr .= 'T';
209
210 // Hour
211 if (!is_null($parts['hour'])) {
212
213 $dateStr .= $parts['hour'];
214
215 if (!is_null($parts['minute'])) {
216 $dateStr .= ':';
217 }
218
219 } else {
220 // We know either minute or second _must_ be set, so we insert a
221 // dash for an empty value.
222 $dateStr .= '-';
223 }
224
225 // Minute
226 if (!is_null($parts['minute'])) {
227
228 $dateStr .= $parts['minute'];
229
230 if (!is_null($parts['second'])) {
231 $dateStr .= ':';
232 }
233
234 } elseif (isset($parts['second'])) {
235 // Dash for empty minute
236 $dateStr .= '-';
237 }
238
239 // Second
240 if (!is_null($parts['second'])) {
241 $dateStr .= $parts['second'];
242 }
243
244 // Timezone
245 if (!is_null($parts['timezone'])) {
246 $dateStr .= $parts['timezone'];
247 }
248
249 return [$dateStr];
250
251 }
252
261 protected function xmlSerializeValue(Xml\Writer $writer) {
262
263 $valueType = strtolower($this->getValueType());
265 $value = '';
266
267 // $d = defined
268 $d = function($part) use ($parts) {
269 return !is_null($parts[$part]);
270 };
271
272 // $r = read
273 $r = function($part) use ($parts) {
274 return $parts[$part];
275 };
276
277 // From the Relax NG Schema.
278 //
279 // # 4.3.1
280 // value-date = element date {
281 // xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" }
282 // }
283 if (($d('year') || $d('month') || $d('date'))
284 && (!$d('hour') && !$d('minute') && !$d('second') && !$d('timezone'))) {
285
286 if ($d('year') && $d('month') && $d('date')) {
287 $value .= $r('year') . $r('month') . $r('date');
288 } elseif ($d('year') && $d('month') && !$d('date')) {
289 $value .= $r('year') . '-' . $r('month');
290 } elseif (!$d('year') && $d('month')) {
291 $value .= '--' . $r('month') . $r('date');
292 } elseif (!$d('year') && !$d('month') && $d('date')) {
293 $value .= '---' . $r('date');
294 }
295
296 // # 4.3.2
297 // value-time = element time {
298 // xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d?)|--\d\d)"
299 // ~ "(Z|[+\-]\d\d(\d\d)?)?" }
300 // }
301 } elseif ((!$d('year') && !$d('month') && !$d('date'))
302 && ($d('hour') || $d('minute') || $d('second'))) {
303
304 if ($d('hour')) {
305 $value .= $r('hour') . $r('minute') . $r('second');
306 } elseif ($d('minute')) {
307 $value .= '-' . $r('minute') . $r('second');
308 } elseif ($d('second')) {
309 $value .= '--' . $r('second');
310 }
311
312 $value .= $r('timezone');
313
314 // # 4.3.3
315 // value-date-time = element date-time {
316 // xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?"
317 // ~ "(Z|[+\-]\d\d(\d\d)?)?" }
318 // }
319 } elseif ($d('date') && $d('hour')) {
320
321 if ($d('year') && $d('month') && $d('date')) {
322 $value .= $r('year') . $r('month') . $r('date');
323 } elseif (!$d('year') && $d('month') && $d('date')) {
324 $value .= '--' . $r('month') . $r('date');
325 } elseif (!$d('year') && !$d('month') && $d('date')) {
326 $value .= '---' . $r('date');
327 }
328
329 $value .= 'T' . $r('hour') . $r('minute') . $r('second') .
330 $r('timezone');
331
332 }
333
334 $writer->writeElement($valueType, $value);
335
336 }
337
348 function setRawMimeDirValue($val) {
349
350 $this->setValue($val);
351
352 }
353
360
361 return implode($this->delimiter, $this->getParts());
362
363 }
364
387 function validate($options = 0) {
388
389 $messages = parent::validate($options);
390 $value = $this->getValue();
391
392 try {
394 } catch (InvalidDataException $e) {
395 $messages[] = [
396 'level' => 3,
397 'message' => 'The supplied value (' . $value . ') is not a correct DATE-AND-OR-TIME property',
398 'node' => $this,
399 ];
400 }
401
402 return $messages;
403
404 }
405}
An exception for terminatinating execution or to throw for unit testing.
static parseVCardDateTime($date)
This method parses a vCard date and or time value.
static parseVCardDateAndOrTime($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.
count()
Returns the number of elements.
Definition: Node.php:177
setParts(array $parts)
Sets a multi-valued property.
xmlSerializeValue(Xml\Writer $writer)
This method serializes only the value of a property.
getJsonValue()
Returns the value, in the format it should be encoded for json.
setDateTime(DateTimeInterface $dt)
Sets the property as a DateTime object.
getValueType()
Returns the type of value.
getRawMimeDirValue()
Returns a raw mime-dir representation of the value.
validate($options=0)
Validates the node for correctness.
getDateTime()
Returns a date-time value.
setRawMimeDirValue($val)
Sets a raw value coming from a mimedir (iCalendar/vCard) file.
setValue($value)
Updates the current value.
getParts()
Returns a multi-valued property.
Definition: Property.php:152
getValue()
Returns the current value.
Definition: Property.php:115
iCalendar/vCard/jCal/jCard/xCal/xCard writer object.
Definition: Writer.php:17
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$messages
Definition: en.php:5
$r
Definition: example_031.php:79