ILIAS  release_8 Revision v8.24
class.ilDateTime.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
5/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
6
8const IL_CAL_DATE = 2;
9const IL_CAL_UNIX = 3;
14
15const IL_CAL_YEAR = 'year';
16const IL_CAL_MONTH = 'month';
17const IL_CAL_WEEK = 'week';
18const IL_CAL_DAY = 'day';
19const IL_CAL_HOUR = 'hour';
20const IL_CAL_SECOND = 'second';
21
29{
30 public const YEAR = 'year';
31 public const MONTH = 'month';
32 public const WEEK = 'week';
33 public const DAY = 'day';
34 public const HOUR = 'hour';
35 public const MINUTE = 'minute';
36 public const SECOND = 'second';
37
38 protected ilLogger $log;
39 protected ?ilTimeZone $timezone = null;
40 protected ?ilTimeZone $default_timezone = null;
41 protected ?DateTime $dt_obj = null;
42
50 public function __construct($a_date = null, int $a_format = 0, string $a_tz = '')
51 {
52 global $DIC;
53
54 $this->log = $DIC->logger()->cal();
55
56 try {
57 $this->timezone = ilTimeZone::_getInstance($a_tz);
58 $this->default_timezone = ilTimeZone::_getInstance('');
59 $this->setDate($a_date, $a_format);
60 } catch (ilTimeZoneException $exc) {
61 $this->log->warning($exc->getMessage());
62 throw new ilDateTimeException('Unsupported timezone given. Timezone: ' . $a_tz);
63 }
64 }
65
66 public function __clone()
67 {
68 if ($this->dt_obj) {
69 $this->dt_obj = clone $this->dt_obj;
70 }
71 }
72
73 public function __sleep()
74 {
75 return array('timezone', 'default_timezone', 'dt_obj');
76 }
77
78 public function __wakeup()
79 {
80 global $DIC;
81 $this->log = $DIC->logger()->cal();
82 }
83
88 public function isNull(): bool
89 {
90 return !($this->dt_obj instanceof DateTime);
91 }
92
98 public function switchTimeZone(string $a_timezone_identifier = ''): void
99 {
100 try {
101 $this->timezone = ilTimeZone::_getInstance($a_timezone_identifier);
102 return;
103 } catch (ilTimeZoneException $e) {
104 $this->log->warning('Unsupported timezone given: ' . $a_timezone_identifier);
105 throw new ilDateTimeException('Unsupported timezone given. Timezone: ' . $a_timezone_identifier);
106 }
107 }
108
109 public function getTimeZoneIdentifier(): string
110 {
111 return $this->timezone->getIdentifier();
112 }
113
124 public static function _before(
125 ilDateTime $start,
126 ilDateTime $end,
127 string $a_compare_field = '',
128 string $a_tz = ''
129 ): bool {
130 if ($start->isNull() || $end->isNull()) {
131 return false;
132 }
133
134 switch ($a_compare_field) {
135 case IL_CAL_YEAR:
136 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
137
138 case IL_CAL_MONTH:
139 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
140
141 case IL_CAL_DAY:
142 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
143
144 case '':
145 default:
146 return $start->dt_obj < $end->dt_obj;
147
148 }
149 }
150
159 public static function _equals(
160 ilDateTime $start,
161 ilDateTime $end,
162 string $a_compare_field = '',
163 string $a_tz = ''
164 ): bool {
165 if ($start->isNull() || $end->isNull()) {
166 return false;
167 }
168
169 switch ($a_compare_field) {
170 case IL_CAL_YEAR:
171 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
172
173 case IL_CAL_MONTH:
174 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
175
176 case IL_CAL_DAY:
177 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
178
179 case '':
180 default:
181 return $start->dt_obj == $end->dt_obj;
182
183 }
184 }
185
197 public static function _after(
198 ilDateTime $start,
199 ilDateTime $end,
200 string $a_compare_field = '',
201 string $a_tz = ''
202 ): bool {
203 if ($start->isNull() || $end->isNull()) {
204 return false;
205 }
206
207 switch ($a_compare_field) {
208 case IL_CAL_YEAR:
209 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
210
211 case IL_CAL_MONTH:
212 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
213
214 case IL_CAL_DAY:
215 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
216
217 case '':
218 default:
219 return $start->dt_obj > $end->dt_obj;
220
221 }
222 }
223
227 public static function _within(
228 ilDateTime $dt,
229 ilDateTime $start,
230 ilDateTime $end,
231 string $a_compare_field = '',
232 string $a_tz = ''
233 ): bool {
234 return
235 (ilDateTime::_after($dt, $start, $a_compare_field, $a_tz) or ilDateTime::_equals(
236 $dt,
237 $start,
238 $a_compare_field,
239 $a_tz
240 )) &&
241 (ilDateTime::_before($dt, $end, $a_compare_field, $a_tz) or ilDateTime::_equals(
242 $dt,
243 $end,
244 $a_compare_field,
245 $a_tz
246 ));
247 }
248
255 public function increment(string $a_type, int $a_count = 1): ?int
256 {
257 if ($this->isNull()) {
258 return null;
259 }
260
261 $sub = ($a_count < 0);
262 $count_str = abs($a_count);
263
264 switch ($a_type) {
265 case self::YEAR:
266 $count_str .= 'year';
267 break;
268
269 case self::MONTH:
270 $count_str .= 'month';
271 break;
272
273 case self::WEEK:
274 $count_str .= 'week';
275 break;
276
277 case self::DAY:
278 $count_str .= 'day';
279 break;
280
281 case self::HOUR:
282 $count_str .= 'hour';
283 break;
284
285 case self::MINUTE:
286 $count_str .= 'minute';
287 break;
288
289 case self::SECOND:
290 $count_str .= 'second';
291 break;
292 }
293
294 $interval = date_interval_create_from_date_string($count_str);
295 if (!$sub) {
296 $this->dt_obj->add($interval);
297 } else {
298 $this->dt_obj->sub($interval);
299 }
300 return $this->getUnixTime();
301 }
302
303 public function getUnixTime(): ?int
304 {
305 if (!$this->isNull()) {
306 return $this->dt_obj->getTimestamp();
307 }
308 return null;
309 }
310
311 protected function parsePartsToDate(
312 int $a_year,
313 int $a_month,
314 int $a_day,
315 ?int $a_hour = null,
316 ?int $a_min = null,
317 ?int $a_sec = null,
318 ?string $a_timezone = null
319 ): ?DateTime {
320 $a_year = $a_year;
321 $a_month = $a_month;
322 $a_day = $a_day;
323
324 if (!$a_year) {
325 return null;
326 }
327 $date = null;
328 try {
329 $a_hour = (int) $a_hour;
330 $a_min = (int) $a_min;
331 $a_sec = (int) $a_sec;
332
333 $format = $a_year . '-' . $a_month . '-' . $a_day;
334
335 if ($a_hour !== null) {
336 $format .= ' ' . $a_hour . ':' . $a_min . ':' . $a_sec;
337
338 // use current timezone if no other given
339 if (!$a_timezone) {
340 $a_timezone = $this->getTimeZoneIdentifier();
341 }
342
343 $date = new DateTime($format, new DateTimeZone($a_timezone));
344 } else {
345 $date = new DateTime($format);
346 }
347 } catch (Exception $ex) {
348 // :TODO: do anything?
349 }
350 return ($date instanceof DateTime)
351 ? $date
352 : null;
353 }
354
360 public function setDate($a_date, int $a_format): void
361 {
362 $this->dt_obj = null;
363
364 if (!$a_date) {
365 return;
366 }
367
368 switch ($a_format) {
369 case IL_CAL_UNIX:
370 try {
371 $this->dt_obj = new DateTime('@' . $a_date);
372 $this->dt_obj->setTimezone(new DateTimeZone($this->getTimeZoneIdentifier()));
373 } catch (Exception $ex) {
374 $message = 'Cannot parse date: ' . $a_date . ' with format ' . $a_format;
375 $this->log->warning($message);
376 throw new ilDateTimeException($message);
377 }
378 break;
379
380 case IL_CAL_DATETIME:
381 $matches = preg_match(
382 '/^(\d{4})-?(\d{2})-?(\d{2})([T\s]?(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?(Z|[\+\-]\d{2}:?\d{2})?)$/i',
383 $a_date,
384 $d_parts
385 );
386 if ($matches < 1) {
387 $this->log->warning('Cannot parse date: ' . $a_date);
388 $this->log->warning(print_r($matches, true));
389 $this->log->logStack(ilLogLevel::WARNING);
390 throw new ilDateTimeException('Cannot parse date: ' . $a_date);
391 }
392
393 $tz_id = (isset($d_parts[9]) && $d_parts[9] === 'Z')
394 ? 'UTC'
395 : $this->getTimeZoneIdentifier();
396 $this->dt_obj = $this->parsePartsToDate(
397 (int) $d_parts[1],
398 (int) $d_parts[2],
399 (int) $d_parts[3],
400 (int) $d_parts[5],
401 (int) $d_parts[6],
402 (int) $d_parts[7],
403 $tz_id
404 );
405 break;
406
407 case IL_CAL_DATE:
408 try {
409 // Pure dates are not timezone sensible.
410 $this->dt_obj = new DateTime($a_date, new DateTimeZone('UTC'));
411 } catch (Exception $ex) {
412 $this->log->warning('Cannot parse date : ' . $a_date);
413 throw new ilDateTimeException('Cannot parse date: ' . $a_date);
414 }
415 break;
416
418 // Format like getdate parameters
419 $this->dt_obj = $this->parsePartsToDate(
420 (int) $a_date['year'],
421 (int) $a_date['mon'],
422 (int) $a_date['mday'],
423 (int) $a_date['hours'],
424 (int) $a_date['minutes'],
425 (int) ($a_date['seconds'] ?? 0),
426 $this->getTimeZoneIdentifier()
427 );
428 break;
429
430 case IL_CAL_TIMESTAMP:
431 if (!preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $a_date, $d_parts)) {
432 $this->log->warning('Cannot parse date: ' . $a_date);
433 throw new ilDateTimeException('Cannot parse date.');
434 }
435 $this->dt_obj = $this->parsePartsToDate(
436 (int) $d_parts[1],
437 (int) $d_parts[2],
438 (int) $d_parts[3],
439 (int) $d_parts[4],
440 (int) $d_parts[5],
441 (int) $d_parts[6],
442 $this->getTimeZoneIdentifier()
443 );
444 break;
445
446 case IL_CAL_ISO_8601:
451 $this->dt_obj = DateTime::createFromFormat(
452 DateTime::ATOM,
453 $a_date,
454 new DateTimeZone($this->getTimeZoneIdentifier())
455 );
456 break;
457 }
458 // remove set timezone since it does not influence the internal date.
459 // the tz must be passed in the moment of the creation of the date object.
460 }
461
466 public function get(int $a_format, string $a_format_str = '', string $a_tz = '')
467 {
468 if ($this->isNull()) {
469 return null;
470 }
471
472 $timezone = $this->default_timezone;
473 if ($a_tz) {
474 try {
475 $timezone = ilTimeZone::_getInstance($a_tz);
476 } catch (ilTimeZoneException $exc) {
477 $this->log->warning('Invalid timezone given. Timezone: ' . $a_tz);
478 }
479 }
480 $out_date = clone($this->dt_obj);
481 $out_date->setTimezone(new DateTimeZone($timezone->getIdentifier()));
482
483 $date = null;
484 switch ($a_format) {
485 case IL_CAL_UNIX:
486 // timezone unrelated
487 $date = $this->getUnixTime();
488 break;
489
490 case IL_CAL_DATE:
491 $date = $out_date->format('Y-m-d');
492 break;
493
494 case IL_CAL_DATETIME:
495 $date = $out_date->format('Y-m-d H:i:s');
496 break;
497
498 case IL_CAL_FKT_DATE:
499 $date = $out_date->format($a_format_str);
500 break;
501
503 $date = array(
504 'seconds' => (int) $out_date->format('s')
505 ,
506 'minutes' => (int) $out_date->format('i')
507 ,
508 'hours' => (int) $out_date->format('G')
509 ,
510 'mday' => (int) $out_date->format('j')
511 ,
512 'wday' => (int) $out_date->format('w')
513 ,
514 'mon' => (int) $out_date->format('n')
515 ,
516 'year' => (int) $out_date->format('Y')
517 ,
518 'yday' => (int) $out_date->format('z')
519 ,
520 'weekday' => $out_date->format('l')
521 ,
522 'month' => $out_date->format('F')
523 ,
524 'isoday' => (int) $out_date->format('N')
525 );
526 break;
527
528 case IL_CAL_ISO_8601:
529 $date = $out_date->format('c');
530 break;
531
532 case IL_CAL_TIMESTAMP:
533 $date = $out_date->format('YmdHis');
534 break;
535 }
536 return $date;
537 }
538
546 public function __toString(): string
547 {
548 return $this->get(IL_CAL_DATETIME) . '<br>';
549 }
550}
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
const IL_CAL_WEEK
const IL_CAL_ISO_8601
const IL_CAL_TIMESTAMP
const IL_CAL_UNIX
const IL_CAL_YEAR
const IL_CAL_DATETIME
const IL_CAL_MONTH
const IL_CAL_FKT_DATE
const IL_CAL_HOUR
const IL_CAL_DAY
const IL_CAL_SECOND
Class for DateTime exceptions.
@classDescription Date and time handling
parsePartsToDate(int $a_year, int $a_month, int $a_day, ?int $a_hour=null, ?int $a_min=null, ?int $a_sec=null, ?string $a_timezone=null)
setDate($a_date, int $a_format)
Set date.
isNull()
Check if a date is null (Datetime == '0000-00-00 00:00:00', unixtime == 0,...)
__construct($a_date=null, int $a_format=0, string $a_tz='')
Create new date object.
static _after(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
DateTime $dt_obj
static _within(ilDateTime $dt, ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
Check whether an date is within a date duration given by start and end.
static _equals(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
Check if two date are equal.
__toString()
to string for date time objects Output is user time zone @access public
ilTimeZone $timezone
switchTimeZone(string $a_timezone_identifier='')
Switch timezone.
increment(string $a_type, int $a_count=1)
ilTimeZone $default_timezone
static _before(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
Component logger with individual log levels by component id.
Class for TimeZone exceptions.
This class offers methods for timezone handling.
static _getInstance(string $a_tz='')
get instance by timezone
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
return['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
global $DIC
Definition: feed.php:28
$format
Definition: metadata.php:235
$message
Definition: xapiexit.php:32