ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilDateTime.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5include_once('Services/Calendar/classes/class.ilDateTimeException.php');
6include_once('Services/Calendar/classes/class.ilTimeZone.php');
7
8
9define('IL_CAL_DATETIME', 1);
10define('IL_CAL_DATE', 2);
11define('IL_CAL_UNIX', 3);
12define('IL_CAL_FKT_DATE', 4);
13define('IL_CAL_FKT_GETDATE', 5);
14define('IL_CAL_TIMESTAMP', 6);
15define('IL_CAL_ISO_8601', 7);
16
17define('IL_CAL_YEAR', 'year');
18define('IL_CAL_MONTH', 'month');
19define('IL_CAL_WEEK', 'week');
20define('IL_CAL_DAY', 'day');
21define('IL_CAL_HOUR', 'hour');
22
23
33{
34 const YEAR = 'year';
35 const MONTH = 'month';
36 const WEEK = 'week';
37 const DAY = 'day';
38 const HOUR = 'hour';
39 const MINUTE = 'minute';
40
41 protected $log;
42
43 protected $timezone = null;
44 protected $default_timezone = null;
45
49 protected $dt_obj; // [DateTime]
50
51
52
63 public function __construct($a_date = null, $a_format = 0, $a_tz = '')
64 {
65 global $ilLog;
66
67 $this->log = $ilLog;
68
69 try {
70 $this->timezone = ilTimeZone::_getInstance($a_tz);
71 $this->default_timezone = ilTimeZone::_getInstance('');
72
73 $this->setDate($a_date, $a_format);
74 } catch (ilTimeZoneException $exc) {
75 $this->log->write(__METHOD__ . ': ' . $exc->getMessage());
76 throw new ilDateTimeException('Unsupported timezone given. Timezone: ' . $a_tz);
77 }
78 }
79
80 public function __clone()
81 {
82 if ($this->dt_obj) {
83 $this->dt_obj = clone $this->dt_obj;
84 }
85 }
86
87 public function __sleep()
88 {
89 return array('timezone', 'default_timezone', 'dt_obj');
90 }
91
92 public function __wakeup()
93 {
94 global $ilLog;
95
96 $this->log = $ilLog;
97 }
98
104 public function isNull()
105 {
106 return !($this->dt_obj instanceof DateTime);
107 }
108
116 public function switchTimeZone($a_timezone_identifier = '')
117 {
118 try {
119 $this->timezone = ilTimeZone::_getInstance($a_timezone_identifier);
120 return true;
121 } catch (ilTimeZoneException $e) {
122 $this->log->write('Unsupported timezone given: ' . $a_timezone_identifier);
123 throw new ilDateTimeException('Unsupported timezone given. Timezone: ' . $a_timezone_identifier);
124 }
125 }
126
133 public function getTimeZoneIdentifier()
134 {
135 return $this->timezone->getIdentifier();
136 }
137
152 public static function _before(ilDateTime $start, ilDateTime $end, $a_compare_field = '', $a_tz = '')
153 {
154 if ($start->isNull() || $end->isNull()) {
155 return false;
156 }
157
158 switch ($a_compare_field) {
159 case IL_CAL_YEAR:
160 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
161
162 case IL_CAL_MONTH:
163 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
164
165 case IL_CAL_DAY:
166 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) < $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
167
168 case '':
169 default:
170 return $start->dt_obj < $end->dt_obj;
171
172 }
173 }
174
187 public static function _equals(ilDateTime $start, ilDateTime $end, $a_compare_field = '', $a_tz = '')
188 {
189 if ($start->isNull() || $end->isNull()) {
190 return false;
191 }
192
193 switch ($a_compare_field) {
194 case IL_CAL_YEAR:
195 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
196
197 case IL_CAL_MONTH:
198 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
199
200 case IL_CAL_DAY:
201 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) == $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
202
203 case '':
204 default:
205 return $start->dt_obj == $end->dt_obj;
206
207 }
208 }
209
222 public static function _after(ilDateTime $start, ilDateTime $end, $a_compare_field = '', $a_tz = '')
223 {
224 if ($start->isNull() || $end->isNull()) {
225 return false;
226 }
227
228 switch ($a_compare_field) {
229 case IL_CAL_YEAR:
230 return $start->get(IL_CAL_FKT_DATE, 'Y', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Y', $a_tz);
231
232 case IL_CAL_MONTH:
233 return (int) $start->get(IL_CAL_FKT_DATE, 'Ym', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Ym', $a_tz);
234
235 case IL_CAL_DAY:
236 return (int) $start->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz) > $end->get(IL_CAL_FKT_DATE, 'Ymd', $a_tz);
237
238 case '':
239 default:
240 return $start->dt_obj > $end->dt_obj;
241
242 }
243 }
244
253 public static function _within(ilDateTime $dt, ilDateTime $start, ilDateTime $end, $a_compare_field = '', $a_tz = '')
254 {
255 return
256 (ilDateTime::_after($dt, $start, $a_compare_field, $a_tz) or ilDateTime::_equals($dt, $start, $a_compare_field, $a_tz)) &&
257 (ilDateTime::_before($dt, $end, $a_compare_field, $a_tz) or ilDateTime::_equals($dt, $end, $a_compare_field, $a_tz));
258 }
259
268 public function increment($a_type, $a_count = 1)
269 {
270 if ($this->isNull()) {
271 return;
272 }
273
274 $sub = ($a_count < 0);
275 $count_str = abs($a_count);
276
277 switch ($a_type) {
278 case self::YEAR:
279 $count_str .= 'year';
280 break;
281
282 case self::MONTH:
283 $count_str .= 'month';
284 break;
285
286 case self::WEEK:
287 $count_str .= 'week';
288 break;
289
290 case self::DAY:
291 $count_str .= 'day';
292 break;
293
294 case self::HOUR:
295 $count_str .= 'hour';
296 break;
297
298 case self::MINUTE:
299 $count_str .= 'minute';
300 break;
301 }
302
303 $interval = date_interval_create_from_date_string($count_str);
304 if (!$sub) {
305 $this->dt_obj->add($interval);
306 } else {
307 $this->dt_obj->sub($interval);
308 }
309
310 // ???
311 return $this->getUnixTime();
312 }
313
320 public function getUnixTime()
321 {
322 if (!$this->isNull()) {
323 return $this->dt_obj->getTimestamp();
324 }
325 }
326
333 public function getUTCOffset()
334 {
335 if (!$this->isNull()) {
336 // already correct/current timezone?
337 $offset = $this->dt_obj->getOffset();
338
339 // TODO: This is wrong: calculate UTC offset of given date
340 // $offset = mktime(0,0,0,2,1,1970) - gmmktime(0,0,0,2,1,1970);
341 }
342 return $offset;
343 }
344
345 protected function parsePartsToDate($a_year, $a_month, $a_day, $a_hour = null, $a_min = null, $a_sec = null, $a_timezone = null)
346 {
347 $a_year = (int) $a_year;
348 $a_month = (int) $a_month;
349 $a_day = (int) $a_day;
350
351 if (!$a_year) {
352 return;
353 }
354
355 try {
356 $a_hour = (int) $a_hour;
357 $a_min = (int) $a_min;
358 $a_sec = (int) $a_sec;
359
360 $format = $a_year . '-' . $a_month . '-' . $a_day;
361
362 if ($a_hour !== null) {
363 $format .= ' ' . (int) $a_hour . ':' . (int) $a_min . ':' . (int) $a_sec;
364
365 // use current timezone if no other given
366 if (!$a_timezone) {
367 $a_timezone = $this->getTimeZoneIdentifier();
368 }
369
370 $date = new DateTime($format, new DateTimeZone($a_timezone));
371 } else {
372 $date = new DateTime($format);
373 }
374 } catch (Exception $ex) {
375 // :TODO: do anything?
376 }
377 return ($date instanceof DateTime)
378 ? $date
379 : null;
380 }
381
392 public function setDate($a_date, $a_format)
393 {
394 $this->dt_obj = null;
395
396 if (!$a_date) {
397 return;
398 }
399
400 switch ($a_format) {
401 case IL_CAL_UNIX:
402 try {
403 $this->dt_obj = new DateTime('@' . $a_date);
404 $this->dt_obj->setTimezone(new DateTimeZone($this->getTimeZoneIdentifier()));
405 } catch (Exception $ex) {
406 $message = 'Cannot parse date: ' . $a_date . ' with format ' . $a_format;
407 $this->log->write($message);
408 throw new ilDateTimeException($message);
409 }
410 break;
411
412 case IL_CAL_DATETIME:
413 $matches = preg_match('/^(\d{4})-?(\d{2})-?(\d{2})([T\s]?(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?(Z|[\+\-]\d{2}:?\d{2})?)$/i', $a_date, $d_parts);
414 if ($matches < 1) {
415 $this->log->write(__METHOD__ . ': Cannot parse date: ' . $a_date);
416 $this->log->write(__METHOD__ . ': ' . print_r($matches, true));
417 $this->log->logStack();
418 throw new ilDateTimeException('Cannot parse date: ' . $a_date);
419 }
420
421 $tz_id = ($d_parts[9] == 'Z')
422 ? 'UTC'
423 : $this->getTimeZoneIdentifier();
424 $this->dt_obj = $this->parsePartsToDate(
425 $d_parts[1],
426 $d_parts[2],
427 $d_parts[3],
428 $d_parts[5],
429 $d_parts[6],
430 $d_parts[7],
431 $tz_id
432 );
433 break;
434
435 case IL_CAL_DATE:
436 try {
437 // Pure dates are not timezone sensible.
438 $this->dt_obj = new DateTime($a_date, new DateTimeZone('UTC'));
439 } catch (Exception $ex) {
440 $this->log->write(__METHOD__ . ': Cannot parse date: ' . $a_date);
441 throw new ilDateTimeException('Cannot parse date: ' . $a_date);
442 }
443 break;
444
446 // Format like getdate parameters
447 $this->dt_obj = $this->parsePartsToDate(
448 $a_date['year'],
449 $a_date['mon'],
450 $a_date['mday'],
451 $a_date['hours'],
452 $a_date['minutes'],
453 $a_date['seconds'],
454 $this->getTimeZoneIdentifier()
455 );
456 break;
457
458 case IL_CAL_TIMESTAMP:
459 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $a_date, $d_parts) == false) {
460 $this->log->write(__METHOD__ . ': Cannot parse date: ' . $a_date);
461 throw new ilDateTimeException('Cannot parse date: ' . $a_date);
462 }
463 $this->dt_obj = $this->parsePartsToDate(
464 $d_parts[1],
465 $d_parts[2],
466 $d_parts[3],
467 $d_parts[4],
468 $d_parts[5],
469 $d_parts[6],
470 $this->getTimeZoneIdentifier()
471 );
472 break;
473
474 case IL_CAL_ISO_8601:
475 $this->dt_obj = DateTime::createFromFormat(
476 DateTime::ISO8601,
477 $a_date,
478 new DateTimeZone($this->getTimeZoneIdentifier())
479 );
480 break;
481 }
482
483 // remove set timezone since it does not influence the internal date.
484 // the tz must be passed in the moment of the creation of the date object.
485 return true;
486 }
487
496 public function get($a_format, $a_format_str = '', $a_tz = '')
497 {
498 if ($this->isNull()) {
499 return;
500 }
501
502 if ($a_tz) {
503 try {
505 } catch (ilTimeZoneException $exc) {
506 $this->log->write(__METHOD__ . ': Invalid timezone given. Timezone: ' . $a_tz);
507 }
508 } else {
510 }
511
512 $out_date = clone($this->dt_obj);
513 $out_date->setTimezone(new DateTimeZone($timezone->getIdentifier()));
514
515 switch ($a_format) {
516 case IL_CAL_UNIX:
517 // timezone unrelated
518 $date = $this->getUnixTime();
519 break;
520
521 case IL_CAL_DATE:
522 $date = $out_date->format('Y-m-d');
523 break;
524
525 case IL_CAL_DATETIME:
526 $date = $out_date->format('Y-m-d H:i:s');
527 break;
528
529 case IL_CAL_FKT_DATE:
530 $date = $out_date->format($a_format_str);
531 break;
532
534 $date = array(
535 'seconds' => (int) $out_date->format('s')
536 ,'minutes' => (int) $out_date->format('i')
537 ,'hours' => (int) $out_date->format('G')
538 ,'mday' => (int) $out_date->format('j')
539 ,'wday' => (int) $out_date->format('w')
540 ,'mon' => (int) $out_date->format('n')
541 ,'year' => (int) $out_date->format('Y')
542 ,'yday' => (int) $out_date->format('z')
543 ,'weekday' => $out_date->format('l')
544 ,'month' => $out_date->format('F')
545 ,'isoday' => (int) $out_date->format('N')
546 );
547 break;
548
549 case IL_CAL_ISO_8601:
550 $date = $out_date->format('c');
551 break;
552
553 case IL_CAL_TIMESTAMP:
554 $date = $out_date->format('YmdHis');
555 break;
556 }
557
558 return $date;
559 }
560
569 public function __toString()
570 {
571 return $this->get(IL_CAL_DATETIME) . '<br>';
572 }
573}
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
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_DAY
Class for DateTime exceptions.
@classDescription Date and time handling
static _equals(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check if two date are equal.
switchTimeZone($a_timezone_identifier='')
Switch timezone.
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
get($a_format, $a_format_str='', $a_tz='')
get formatted date
isNull()
Check if a date is null (Datetime == '0000-00-00 00:00:00', unixtime == 0,...)
__construct($a_date=null, $a_format=0, $a_tz='')
Create new date object.
getTimeZoneIdentifier()
get timezone identifier
getUTCOffset()
get UTC offset
__toString()
to string for date time objects Output is user time zone
getUnixTime()
get unix time
static _within(ilDateTime $dt, ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check whether an date is within a date duration given by start and end.
increment($a_type, $a_count=1)
increment
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
parsePartsToDate($a_year, $a_month, $a_day, $a_hour=null, $a_min=null, $a_sec=null, $a_timezone=null)
setDate($a_date, $a_format)
Set date.
Class for TimeZone exceptions.
static _getInstance($a_tz='')
get instance by timezone
$format
Definition: metadata.php:141
$end
Definition: saml1-acs.php:18
catch(Exception $e) $message
$a_type
Definition: workflow.php:92