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 
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 
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 
445  case IL_CAL_FKT_GETDATE:
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 
533  case IL_CAL_FKT_GETDATE:
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 }
Set timezone
$format
Definition: metadata.php:141
__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.
$end
Definition: saml1-acs.php:18
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:92
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.
catch(Exception $e) $message
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