ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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
46 protected $dt_obj; // [DateTime]
47
48
49
60 public function __construct($a_date = null,$a_format = 0,$a_tz = '')
61 {
62 global $ilLog;
63
64 $this->log = $ilLog;
65
66 try
67 {
68 $this->timezone = ilTimeZone::_getInstance($a_tz);
69 $this->default_timezone = ilTimeZone::_getInstance('');
70
71 $this->setDate($a_date,$a_format);
72 }
73 catch(ilTimeZoneException $exc)
74 {
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 {
84 $this->dt_obj = clone $this->dt_obj;
85 }
86 }
87
88 public function __sleep()
89 {
90 return array('timezone', 'default_timezone', 'dt_obj');
91 }
92
93 public function __wakeup()
94 {
95 global $ilLog;
96
97 $this->log = $ilLog;
98 }
99
105 public function isNull()
106 {
107 return !($this->dt_obj instanceof DateTime);
108 }
109
117 public function switchTimeZone($a_timezone_identifier = '')
118 {
119 try
120 {
121 $this->timezone = ilTimeZone::_getInstance($a_timezone_identifier);
122 return true;
123 }
124 catch(ilTimeZoneException $e)
125 {
126 $this->log->write('Unsupported timezone given: '.$a_timezone_identifier);
127 throw new ilDateTimeException('Unsupported timezone given. Timezone: '.$a_timezone_identifier);
128 }
129 }
130
137 public function getTimeZoneIdentifier()
138 {
139 return $this->timezone->getIdentifier();
140 }
141
156 public static function _before(ilDateTime $start,ilDateTime $end,$a_compare_field = '',$a_tz = '')
157 {
158 if($start->isNull() || $end->isNull())
159 {
160 return;
161 }
162
163 switch($a_compare_field)
164 {
165 case IL_CAL_YEAR:
166 return $start->get(IL_CAL_FKT_DATE,'Y',$a_tz) < $end->get(IL_CAL_FKT_DATE,'Y',$a_tz);
167
168 case IL_CAL_MONTH:
169 return (int) $start->get(IL_CAL_FKT_DATE,'Ym',$a_tz) < $end->get(IL_CAL_FKT_DATE,'Ym',$a_tz);
170
171 case IL_CAL_DAY:
172 return (int) $start->get(IL_CAL_FKT_DATE,'Ymd',$a_tz) < $end->get(IL_CAL_FKT_DATE,'Ymd',$a_tz);
173
174 case '':
175 default:
176 return $start->dt_obj < $end->dt_obj;
177
178 }
179 }
180
192 public static function _equals(ilDateTime $start,ilDateTime $end,$a_compare_field = '',$a_tz = '')
193 {
194 if($start->isNull() || $end->isNull())
195 {
196 return;
197 }
198
199 switch($a_compare_field)
200 {
201 case IL_CAL_YEAR:
202 return $start->get(IL_CAL_FKT_DATE,'Y',$a_tz) == $end->get(IL_CAL_FKT_DATE,'Y',$a_tz);
203
204 case IL_CAL_MONTH:
205 return (int) $start->get(IL_CAL_FKT_DATE,'Ym',$a_tz) == $end->get(IL_CAL_FKT_DATE,'Ym',$a_tz);
206
207 case IL_CAL_DAY:
208 return (int) $start->get(IL_CAL_FKT_DATE,'Ymd',$a_tz) == $end->get(IL_CAL_FKT_DATE,'Ymd',$a_tz);
209
210 case '':
211 default:
212 return $start->dt_obj == $end->dt_obj;
213
214 }
215 }
216
229 public static function _after(ilDateTime $start,ilDateTime $end,$a_compare_field = '',$a_tz = '')
230 {
231 if($start->isNull() || $end->isNull())
232 {
233 return;
234 }
235
236 switch($a_compare_field)
237 {
238 case IL_CAL_YEAR:
239 return $start->get(IL_CAL_FKT_DATE,'Y',$a_tz) > $end->get(IL_CAL_FKT_DATE,'Y',$a_tz);
240
241 case IL_CAL_MONTH:
242 return (int) $start->get(IL_CAL_FKT_DATE,'Ym',$a_tz) > $end->get(IL_CAL_FKT_DATE,'Ym',$a_tz);
243
244 case IL_CAL_DAY:
245 return (int) $start->get(IL_CAL_FKT_DATE,'Ymd',$a_tz) > $end->get(IL_CAL_FKT_DATE,'Ymd',$a_tz);
246
247 case '':
248 default:
249 return $start->dt_obj > $end->dt_obj;
250
251 }
252 }
253
262 public static function _within(ilDateTime $dt, ilDateTime $start, ilDateTime $end, $a_compare_field = '', $a_tz = '')
263 {
264 return
265 (ilDateTime::_after($dt, $start,$a_compare_field,$a_tz) or ilDateTime::_equals($dt, $start,$a_compare_field,$a_tz)) &&
266 (ilDateTime::_before($dt, $end,$a_compare_field,$a_tz) or ilDateTime::_equals($dt, $end,$a_compare_field,$a_tz));
267 }
268
277 public function increment($a_type,$a_count = 1)
278 {
279 if($this->isNull())
280 {
281 return;
282 }
283
284 $sub = ($a_count < 0);
285 $count_str = abs($a_count);
286
287 switch($a_type)
288 {
289 case self::YEAR:
290 $count_str .= 'year';
291 break;
292
293 case self::MONTH:
294 $count_str .= 'month';
295 break;
296
297 case self::WEEK:
298 $count_str .= 'week';
299 break;
300
301 case self::DAY:
302 $count_str .= 'day';
303 break;
304
305 case self::HOUR:
306 $count_str .= 'hour';
307 break;
308
309 case self::MINUTE:
310 $count_str .= 'minute';
311 break;
312 }
313
314 $interval = date_interval_create_from_date_string($count_str);
315 if(!$sub)
316 {
317 $this->dt_obj->add($interval);
318 }
319 else
320 {
321 $this->dt_obj->sub($interval);
322 }
323
324 // ???
325 return $this->getUnixTime();
326 }
327
334 public function getUnixTime()
335 {
336 if(!$this->isNull())
337 {
338 return $this->dt_obj->getTimestamp();
339 }
340 }
341
348 public function getUTCOffset()
349 {
350 if(!$this->isNull())
351 {
352 // already correct/current timezone?
353 $offset = $this->dt_obj->getOffset();
354
355 // TODO: This is wrong: calculate UTC offset of given date
356 // $offset = mktime(0,0,0,2,1,1970) - gmmktime(0,0,0,2,1,1970);
357 }
358 return $offset;
359 }
360
361 protected function parsePartsToDate($a_year, $a_month, $a_day, $a_hour = null, $a_min = null, $a_sec = null, $a_timezone = null)
362 {
363 $a_year = (int)$a_year;
364 $a_month = (int)$a_month;
365 $a_day = (int)$a_day;
366
367 if(!$a_year)
368 {
369 return;
370 }
371
372 try
373 {
374 $a_hour = (int)$a_hour;
375 $a_min = (int)$a_min;
376 $a_sec = (int)$a_sec;
377
378 $format = $a_year.'-'.$a_month.'-'.$a_day;
379
380 if($a_hour !== null)
381 {
382 $format .= ' '.(int)$a_hour.':'.(int)$a_min.':'.(int)$a_sec;
383
384 // use current timezone if no other given
385 if(!$a_timezone)
386 {
387 $a_timezone = $this->getTimeZoneIdentifier();
388 }
389
390 $date = new DateTime($format, new DateTimeZone($a_timezone));
391 }
392 else
393 {
394 $date = new DateTime($format);
395 }
396 }
397 catch (Exception $ex)
398 {
399 // :TODO: do anything?
400 }
401 return ($date instanceof DateTime)
402 ? $date
403 : null;
404 }
405
414 public function setDate($a_date,$a_format)
415 {
416 $this->dt_obj = null;
417
418 if(!$a_date)
419 {
420 return;
421 }
422
423 switch($a_format)
424 {
425 case IL_CAL_UNIX:
426 try
427 {
428 $this->dt_obj = new DateTime('@'.$a_date);
429 }
430 catch (Exception $ex)
431 {
432 $this->log->write(__METHOD__.': Cannot parse date: '.$a_date);
433 throw new ilDateTimeException('Cannot parse date.');
434 }
435 break;
436
437 case IL_CAL_DATETIME:
438 $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);
439 if($matches < 1)
440 {
441 $this->log->write(__METHOD__.': Cannot parse date: '.$a_date);
442 $this->log->write(__METHOD__.': '.print_r($matches,true));
443 $this->log->logStack();
444 throw new ilDateTimeException('Cannot parse date.');
445 }
446
447 $tz_id = ($d_parts[9] == 'Z')
448 ? 'UTC'
449 : null;
450 $this->dt_obj = $this->parsePartsToDate($d_parts[1], $d_parts[2], $d_parts[3],
451 $d_parts[5], $d_parts[6], $d_parts[7], $tz_id);
452 break;
453
454 case IL_CAL_DATE:
455 try
456 {
457 // Pure dates are not timezone sensible.
458 $this->dt_obj = new DateTime($a_date, new DateTimeZone('UTC'));
459 }
460 catch (Exception $ex)
461 {
462 $this->log->write(__METHOD__.': Cannot parse date : '.$a_date);
463 return false;
464 }
465 break;
466
467 case IL_CAL_FKT_GETDATE:
468 // Format like getdate parameters
469 $this->dt_obj = $this->parsePartsToDate($a_date['year'], $a_date['mon'], $a_date['mday'],
470 $a_date['hours'], $a_date['minutes'], $a_date['seconds']);
471 break;
472
473 case IL_CAL_TIMESTAMP:
474 if(preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $a_date,$d_parts) == false)
475 {
476 $this->log->write(__METHOD__.': Cannot parse date: '.$a_date);
477 throw new ilDateTimeException('Cannot parse date.');
478 }
479 $this->dt_obj = $this->parsePartsToDate($d_parts[1], $d_parts[2], $d_parts[3],
480 $d_parts[4], $d_parts[5], $d_parts[6]);
481 break;
482
483 case IL_CAL_ISO_8601:
484 $this->dt_obj = DateTime::createFromFormat(DateTime::ISO8601, $a_date);
485 break;
486 }
487
488 // internally we always use the default timezone
489 if($this->dt_obj)
490 {
491 $this->dt_obj->setTimeZone(new DateTimeZone($this->default_timezone->getIdentifier()));
492 }
493
494 return true;
495 }
496
505 public function get($a_format,$a_format_str = '',$a_tz = '')
506 {
507 if($this->isNull())
508 {
509 return;
510 }
511
512 if($a_tz)
513 {
514 try
515 {
517 }
518 catch(ilTimeZoneException $exc)
519 {
520 $this->log->write(__METHOD__.': Invalid timezone given. Timezone: '.$a_tz);
521 }
522 }
523 else
524 {
526 }
527
528 $out_date = clone($this->dt_obj);
529 $out_date->setTimeZone(new DateTimeZone($timezone->getIdentifier()));
530
531 switch($a_format)
532 {
533 case IL_CAL_UNIX:
534 // timezone unrelated
535 $date = $this->getUnixTime();
536 break;
537
538 case IL_CAL_DATE:
539 $date = $out_date->format('Y-m-d');
540 break;
541
542 case IL_CAL_DATETIME:
543 $date = $out_date->format('Y-m-d H:i:s');
544 break;
545
546 case IL_CAL_FKT_DATE:
547 $date = $out_date->format($a_format_str);
548 break;
549
550 case IL_CAL_FKT_GETDATE:
551 $date = array(
552 'seconds' => (int)$out_date->format('s')
553 ,'minutes' => (int)$out_date->format('i')
554 ,'hours' => (int)$out_date->format('G')
555 ,'mday' => (int)$out_date->format('j')
556 ,'wday' => (int)$out_date->format('w')
557 ,'mon' => (int)$out_date->format('n')
558 ,'year' => (int)$out_date->format('Y')
559 ,'yday' => (int)$out_date->format('z')
560 ,'weekday' => $out_date->format('l')
561 ,'month' => $out_date->format('F')
562 ,'isoday' => (int)$out_date->format('N')
563 );
564 break;
565
566 case IL_CAL_ISO_8601:
567 $date = $out_date->format('c');
568 break;
569
570 case IL_CAL_TIMESTAMP:
571 $date = $out_date->format('YmdHis');
572 break;
573 }
574
575 return $date;
576 }
577
586 public function __toString()
587 {
588 return $this->get(IL_CAL_DATETIME).'<br>';
589 }
590}
591?>
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
$a_type
Definition: workflow.php:93