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 
5 include_once('Services/Calendar/classes/class.ilDateTimeException.php');
6 include_once('Services/Calendar/classes/class.ilTimeZone.php');
7 
8 
9 define('IL_CAL_DATETIME',1);
10 define('IL_CAL_DATE',2);
11 define('IL_CAL_UNIX',3);
12 define('IL_CAL_FKT_DATE',4);
13 define('IL_CAL_FKT_GETDATE',5);
14 define('IL_CAL_TIMESTAMP',6);
15 define('IL_CAL_ISO_8601',7);
16 
17 define('IL_CAL_YEAR','year');
18 define('IL_CAL_MONTH','month');
19 define('IL_CAL_WEEK','week');
20 define('IL_CAL_DAY','day');
21 define('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 ?>
Set timezone
__construct($a_date=null, $a_format=0, $a_tz='')
Create new date object.
const IL_CAL_DATETIME
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.
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.
switchTimeZone($a_timezone_identifier='')
Switch timezone.
const IL_CAL_MONTH
Class for DateTime exceptions.
const IL_CAL_UNIX
__toString()
to string for date time objects Output is user time zone
$a_type
Definition: workflow.php:93
const IL_CAL_DAY
getTimeZoneIdentifier()
get timezone identifier
static _equals(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check if two date are equal.
getUTCOffset()
get UTC offset
Class for TimeZone exceptions.
const IL_CAL_FKT_DATE
const IL_CAL_ISO_8601
Date and time handling
get($a_format, $a_format_str='', $a_tz='')
get formatted date
increment($a_type, $a_count=1)
increment
Create styles array
The data for the language used.
const IL_CAL_FKT_GETDATE
static _getInstance($a_tz='')
get instance by timezone
getUnixTime()
get unix time
const IL_CAL_DATE
setDate($a_date, $a_format)
set date
parsePartsToDate($a_year, $a_month, $a_day, $a_hour=null, $a_min=null, $a_sec=null, $a_timezone=null)
const IL_CAL_TIMESTAMP
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.
isNull()
Check if a date is null (Datetime == &#39;0000-00-00 00:00:00&#39;, unixtime == 0,...)
const IL_CAL_YEAR