35 if ($date instanceof \
ilDate) {
45 $ilUser = $DIC[
'ilUser'];
46 if (!is_object(self::$today)) {
62 $month = $a_month < 10 ?
'0' . $a_month : $a_month;
63 return $a_long ?
$lng->txt(
'month_' . $month .
'_long') :
$lng->txt(
'month_' . $month .
'_short');
75 $lng->loadLanguageModule(
'dateplaner');
76 static $days = array(
'Su',
'Mo',
'Tu',
'We',
'Th',
'Fr',
'Sa',
'Su');
78 return $a_long ?
$lng->txt($days[$a_day] .
'_long') :
$lng->txt($days[$a_day] .
'_short');
92 $start = clone $a_day;
94 $day_diff = $a_weekstart - $start_info[
'isoday'];
95 if (abs($day_diff) === 7) {
99 $day_list->add($start);
100 for ($i = 1; $i < 7; $i++) {
102 $day_list->add($start);
118 $prev_month = ($a_month == 1) ? 12 : $a_month - 1;
119 $prev_year = ($prev_month == 12) ? $a_year - 1 : $a_year;
120 $next_month = $a_month == 12 ? 1 : $a_month + 1;
121 $next_year = $a_month == 12 ? $a_year + 1 : $a_year;
123 $days_in_month = self::_getMaxDayOfMonth($a_year, $a_month);
124 $days_in_prev_month = self::_getMaxDayOfMonth($a_year, $prev_month);
126 $week_day[
'year'] = $a_year;
127 $week_day[
'mon'] = $a_month;
128 $week_day[
'mday'] = 1;
129 $week_day[
'hours'] = 0;
130 $week_day[
'minutes'] = 0;
134 $first_day_offset = (($weekday - $weekstart) < 0) ? 6 : $weekday - $weekstart;
136 for ($i = 0; $i < 42; $i++) {
137 if ($i < $first_day_offset) {
138 $day = $days_in_prev_month - $first_day_offset + $i + 1;
140 $day_list->add(
new ilDate(
146 $days_in_prev_month - $first_day_offset + $i + 1,
151 } elseif ($i < $days_in_month + $first_day_offset) {
152 $day = $i - $first_day_offset + 1;
154 $day_list->add(
new ilDate(
160 $i - $first_day_offset + 1,
166 $day = $i - $days_in_month - $first_day_offset + 1;
167 $day_list->add(
new ilDate(
173 $i - $days_in_month - $first_day_offset + 1,
179 if ($i == 34 and ($day < 15 or $day == $days_in_month)) {
193 if (self::$init_done ==
"done") {
197 $lng->loadLanguageModule(
"jscalendar");
199 "CALENDAR_LANG_JAVASCRIPT",
200 "calendar_javascript",
204 $tpl->setCurrentBlock(
"calendar_javascript");
205 $tpl->setVariable(
"FULL_SUNDAY",
$lng->txt(
"l_su"));
206 $tpl->setVariable(
"FULL_MONDAY",
$lng->txt(
"l_mo"));
207 $tpl->setVariable(
"FULL_TUESDAY",
$lng->txt(
"l_tu"));
208 $tpl->setVariable(
"FULL_WEDNESDAY",
$lng->txt(
"l_we"));
209 $tpl->setVariable(
"FULL_THURSDAY",
$lng->txt(
"l_th"));
210 $tpl->setVariable(
"FULL_FRIDAY",
$lng->txt(
"l_fr"));
211 $tpl->setVariable(
"FULL_SATURDAY",
$lng->txt(
"l_sa"));
212 $tpl->setVariable(
"SHORT_SUNDAY",
$lng->txt(
"s_su"));
213 $tpl->setVariable(
"SHORT_MONDAY",
$lng->txt(
"s_mo"));
214 $tpl->setVariable(
"SHORT_TUESDAY",
$lng->txt(
"s_tu"));
215 $tpl->setVariable(
"SHORT_WEDNESDAY",
$lng->txt(
"s_we"));
216 $tpl->setVariable(
"SHORT_THURSDAY",
$lng->txt(
"s_th"));
217 $tpl->setVariable(
"SHORT_FRIDAY",
$lng->txt(
"s_fr"));
218 $tpl->setVariable(
"SHORT_SATURDAY",
$lng->txt(
"s_sa"));
219 $tpl->setVariable(
"FULL_JANUARY",
$lng->txt(
"l_01"));
220 $tpl->setVariable(
"FULL_FEBRUARY",
$lng->txt(
"l_02"));
221 $tpl->setVariable(
"FULL_MARCH",
$lng->txt(
"l_03"));
222 $tpl->setVariable(
"FULL_APRIL",
$lng->txt(
"l_04"));
223 $tpl->setVariable(
"FULL_MAY",
$lng->txt(
"l_05"));
224 $tpl->setVariable(
"FULL_JUNE",
$lng->txt(
"l_06"));
225 $tpl->setVariable(
"FULL_JULY",
$lng->txt(
"l_07"));
226 $tpl->setVariable(
"FULL_AUGUST",
$lng->txt(
"l_08"));
227 $tpl->setVariable(
"FULL_SEPTEMBER",
$lng->txt(
"l_09"));
228 $tpl->setVariable(
"FULL_OCTOBER",
$lng->txt(
"l_10"));
229 $tpl->setVariable(
"FULL_NOVEMBER",
$lng->txt(
"l_11"));
230 $tpl->setVariable(
"FULL_DECEMBER",
$lng->txt(
"l_12"));
231 $tpl->setVariable(
"SHORT_JANUARY",
$lng->txt(
"s_01"));
232 $tpl->setVariable(
"SHORT_FEBRUARY",
$lng->txt(
"s_02"));
233 $tpl->setVariable(
"SHORT_MARCH",
$lng->txt(
"s_03"));
234 $tpl->setVariable(
"SHORT_APRIL",
$lng->txt(
"s_04"));
235 $tpl->setVariable(
"SHORT_MAY",
$lng->txt(
"s_05"));
236 $tpl->setVariable(
"SHORT_JUNE",
$lng->txt(
"s_06"));
237 $tpl->setVariable(
"SHORT_JULY",
$lng->txt(
"s_07"));
238 $tpl->setVariable(
"SHORT_AUGUST",
$lng->txt(
"s_08"));
239 $tpl->setVariable(
"SHORT_SEPTEMBER",
$lng->txt(
"s_09"));
240 $tpl->setVariable(
"SHORT_OCTOBER",
$lng->txt(
"s_10"));
241 $tpl->setVariable(
"SHORT_NOVEMBER",
$lng->txt(
"s_11"));
242 $tpl->setVariable(
"SHORT_DECEMBER",
$lng->txt(
"s_12"));
243 $tpl->setVariable(
"ABOUT_CALENDAR",
$lng->txt(
"about_calendar"));
244 $tpl->setVariable(
"ABOUT_CALENDAR_LONG",
$lng->txt(
"about_calendar_long"));
245 $tpl->setVariable(
"ABOUT_TIME_LONG",
$lng->txt(
"about_time"));
246 $tpl->setVariable(
"PREV_YEAR",
$lng->txt(
"prev_year"));
247 $tpl->setVariable(
"PREV_MONTH",
$lng->txt(
"prev_month"));
248 $tpl->setVariable(
"GO_TODAY",
$lng->txt(
"go_today"));
249 $tpl->setVariable(
"NEXT_MONTH",
$lng->txt(
"next_month"));
250 $tpl->setVariable(
"NEXT_YEAR",
$lng->txt(
"next_year"));
251 $tpl->setVariable(
"SEL_DATE",
$lng->txt(
"select_date"));
252 $tpl->setVariable(
"DRAG_TO_MOVE",
$lng->txt(
"drag_to_move"));
253 $tpl->setVariable(
"PART_TODAY",
$lng->txt(
"part_today"));
254 $tpl->setVariable(
"DAY_FIRST",
$lng->txt(
"day_first"));
255 $tpl->setVariable(
"CLOSE",
$lng->txt(
"close"));
256 $tpl->setVariable(
"TODAY",
$lng->txt(
"today"));
257 $tpl->setVariable(
"TIME_PART",
$lng->txt(
"time_part"));
258 $tpl->setVariable(
"DEF_DATE_FORMAT",
$lng->txt(
"def_date_format"));
259 $tpl->setVariable(
"TT_DATE_FORMAT",
$lng->txt(
"tt_date_format"));
260 $tpl->setVariable(
"WK",
$lng->txt(
"wk"));
261 $tpl->setVariable(
"TIME",
$lng->txt(
"time"));
262 $tpl->parseCurrentBlock();
263 $tpl->setCurrentBlock(
"CalendarJS");
264 $tpl->setVariable(
"LOCATION_JAVASCRIPT_CALENDAR",
"./Services/Calendar/js/calendar.js");
265 $tpl->setVariable(
"LOCATION_JAVASCRIPT_CALENDAR_SETUP",
"./Services/Calendar/js/calendar-setup.js");
266 $tpl->parseCurrentBlock();
268 self::$init_done =
"done";
273 if (!array_key_exists($a_tz, self::_getShortTimeZoneList())) {
276 $timezone_filename = str_replace(
'/',
'_', $a_tz);
277 $timezone_filename .=
'.ics';
278 return './Services/Calendar/zoneinfo/' . $timezone_filename;
287 'Pacific/Samoa' =>
'GMT-11: Midway Islands, Samoa',
288 'US/Hawaii' =>
'GMT-10:00: Hawaii, Polynesia',
289 'US/Alaska' =>
'GMT-9:00: Alaska',
290 'America/Los_Angeles' =>
'GMT-8:00: Tijuana, Los Angeles, Seattle, Vancouver',
291 'US/Arizona' =>
'GMT-7:00: Arizona',
292 'America/Chihuahua' =>
'GMT-7:00: Chihuahua, La Paz, Mazatlan',
293 'America/Denver' =>
'GMT-7:00: Arizona, Denver, Salt Lake City, Calgary',
294 'America/Chicago' =>
'GMT-6:00: Chicago, Dallas, Kansas City, Winnipeg',
295 'America/Monterrey' =>
'GMT-6:00: Guadalajara, Mexico City, Monterrey',
296 'Canada/Saskatchewan' =>
'GMT-6:00: Saskatchewan',
297 'US/Central' =>
'GMT-6:00: Central America',
298 'America/Bogota' =>
'GMT-5:00: Bogota, Lima, Quito',
299 'US/East-Indiana' =>
'GMT-5:00: East-Indiana',
300 'America/New_York' =>
'GMT-5:00: New York, Miami, Atlanta, Detroit, Toronto',
301 'Canada/Atlantic' =>
'GMT-4:00: Atlantic (Canada)',
302 'America/La_Paz' =>
'GMT-4:00: Carcas, La Paz',
303 'America/Santiago' =>
'GMT-4:00: Santiago',
304 'Canada/Newfoundland' =>
'GMT-3:00: Newfoundland',
305 'Brazil/East' =>
'GMT-3:00: Sao Paulo',
306 'America/Argentina/Buenos_Aires' =>
'GMT-3:00: Buenes Aires, Georgtown',
307 'Etc/GMT+3' =>
'GMT-3:00: Greenland, Uruguay, Surinam',
308 'Atlantic/Cape_Verde' =>
'GMT-2:00: Cape Verde, Greenland, South Georgia',
309 'Atlantic/Azores' =>
'GMT-1:00: Azores',
310 'Africa/Casablanca' =>
'GMT+0:00: Casablanca, Monrovia',
311 'Europe/London' =>
'GMT+0:00: Dublin, Edinburgh, Lisbon, London',
312 'Europe/Berlin' =>
'GMT+1:00: Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna',
313 'Europe/Belgrade' =>
'GMT+1:00: Belgrade, Bratislava, Budapest, Ljubljana, Prague',
314 'Europe/Paris' =>
'GMT+1:00: Brussels, Copenhagen, Paris, Madrid',
315 'Europe/Sarajevo' =>
'GMT+1:00: Sarajevo, Skopje, Warsaw, Zagreb',
316 'Africa/Lagos' =>
'GMT+1:00: West-Central Africa',
317 'Europe/Athens' =>
'GMT+2:00: Athens, Beirut, Istanbul, Minsk',
318 'Europe/Bucharest' =>
'GMT+2:00: Bucharest',
319 'Africa/Harare' =>
'GMT+2:00: Harare, Pratoria',
320 'Europe/Helsinki' =>
'GMT+2:00: Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius',
321 'Asia/Jerusalem' =>
'GMT+2:00: Jerusalem',
322 'Africa/Cairo' =>
'GMT+2:00: Cairo',
323 'Asia/Baghdad' =>
'GMT+3:00: Baghdad',
324 'Asia/Kuwait' =>
'GMT+3:00: Kuwait, Riyadh',
325 'Europe/Moscow' =>
'GMT+3:00: Moscow, Saint Petersburg',
326 'Africa/Nairobi' =>
'GMT+3:00: Nairobi',
327 'Asia/Tehran' =>
'GMT+3:30: Tehran',
328 'Asia/Muscat' =>
'GMT+4:00: Abu Dhabi, Muscat',
329 'Asia/Baku' =>
'GMT+4:00: Baku, Tbilisi, Erivan',
330 'Asia/Kabul' =>
'GMT+4:00: Kabul',
331 'Asia/Karachi' =>
'GMT+5:00: Islamabad, Karachi, Taschkent',
332 'Asia/Yekaterinburg' =>
'GMT+5:00: Yekaterinburg',
333 'Asia/Calcutta' =>
'GMT+5:30: New Dehli',
334 'Asia/Katmandu' =>
'GMT+5:45: Katmandu',
335 'Asia/Novosibirsk' =>
'GMT+6:00: Almaty, Novosibirsk',
336 'Asia/Dhaka' =>
'GMT+6:00: Astana, Dhaka',
337 'Asia/Rangoon' =>
'GMT+6:00: Sri Jayawardenepura, Rangoon',
338 'Asia/Jakarta' =>
'GMT+7:00: Bangkok, Hanoi, Jakarta',
339 'Asia/Krasnoyarsk' =>
'GMT+7:00: Krasnoyarsk',
340 'Asia/Irkutsk' =>
'GMT+8:00: Irkutsk, Ulan Bator',
341 'Asia/Singapore' =>
'GMT+8:00: Kuala Lumpour, Singapore',
342 'Asia/Hong_Kong' =>
'GMT+8:00: Beijing, Chongqing, Hong kong, Urumchi',
343 'Australia/Perth' =>
'GMT+8:00: Perth',
344 'Asia/Taipei' =>
'GMT+8:00: Taipei',
345 'Asia/Yakutsk' =>
'GMT+9:00: Yakutsk',
346 'Asia/Tokyo' =>
'GMT+9:00: Osaka, Sapporo, Tokyo',
347 'Asia/Seoul' =>
'GMT+9:00: Seoul, Darwin, Adelaide',
348 'Australia/Brisbane' =>
'GMT+10:00: Brisbane',
349 'Australia/Sydney' =>
'GMT+10:00: Canberra, Melbourne, Sydney',
350 'Pacific/Guam' =>
'GMT+10:00: Guam, Port Moresby',
351 'Australia/Hobart' =>
'GMT+10:00: Hobart',
352 'Asia/Vladivostok' =>
'GMT+10:00: Vladivostok',
353 'Asia/Magadan' =>
'GMT+11:00: Salomon Islands, New Caledonia, Magadan',
354 'Pacific/Auckland' =>
'GMT+12:00: Auckland, Wellington',
355 'Pacific/Fiji' =>
'GMT+12:00: Fiji, Kamchatka, Marshall-Islands' 365 if ($a_year % 4 == 0) {
367 if ($a_year % 100 == 0) {
383 if (function_exists(
'cal_days_in_month')) {
384 return cal_days_in_month(CAL_GREGORIAN, $a_month, $a_year);
386 return (
int) date(
't', mktime(0, 0, 0, $a_month, 1, $a_year));
396 if (strpos($a_html_color_code,
'#') !== 0 or strlen($a_html_color_code) != 7) {
401 $lum = round(hexdec(substr($a_html_color_code, 1, 2)) * 0.2126 +
402 hexdec(substr($a_html_color_code, 3, 2)) * 0.7152 +
403 hexdec(substr($a_html_color_code, 5, 2)) * 0.0722);
404 return ($lum <= 128) ?
"#FFFFFF" :
"#000000";
415 for ($i = 0; $i < 24; $i++) {
416 $options[$i] = sprintf(
'%02d:00', $i);
421 for ($i = 0; $i < 24; $i++) {
422 $options[$i] = date(
'h a', mktime($i, 0, 0, 1, 1, 2000));
436 bool $a_create =
false 440 $ilDB = $DIC[
'ilDB'];
441 if (isset(self::$default_calendar[$a_usr_id]) and isset(self::$default_calendar[$a_usr_id][$a_type_id])) {
442 return self::$default_calendar[$a_usr_id][$a_type_id];
445 $query =
"SELECT cat_id FROM cal_categories " .
446 "WHERE obj_id = " .
$ilDB->quote($a_usr_id,
'integer') .
" " .
447 "AND type = " .
$ilDB->quote($a_type_id,
'integer');
450 return self::$default_calendar[$a_usr_id][$a_type_id] =
new ilCalendarCategory($row->cat_id);
459 self::$default_calendar[$a_usr_id][$a_type_id]->setType($a_type_id);
461 self::$default_calendar[$a_usr_id][$a_type_id]->setTitle($a_title);
462 self::$default_calendar[$a_usr_id][$a_type_id]->setObjId($a_usr_id);
463 self::$default_calendar[$a_usr_id][$a_type_id]->add();
465 return self::$default_calendar[$a_usr_id][$a_type_id];
474 public static function getUserDateFormat(
int $a_add_time = 0,
bool $a_for_parsing =
false): string
478 $ilUser = $DIC[
'ilUser'];
480 $format = (string) $ilUser->getDateFormat();
486 if ($a_add_time == 2) {
492 if (!$a_for_parsing) {
493 $format = str_replace(
"d",
"DD", $format);
494 $format = str_replace(
"m",
"MM", $format);
495 $format = str_replace(
"i",
"mm", $format);
496 $format = str_replace(
"Y",
"YYYY", $format);
497 $format = str_replace(
"H",
"HH", $format);
498 $format = str_replace(
"h",
"hh", $format);
499 $format = str_replace(
"s",
"ss", $format);
508 $tpl = $DIC->ui()->mainTemplate();
510 if (!self::$init_datetimepicker) {
511 $tpl->addJavaScript(
"./node_modules/moment/min/moment-with-locales.min.js");
514 $tpl->addJavaScript(
"./node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js");
515 $tpl->addJavaScript(
"Services/Form/js/Form.js");
516 self::$init_datetimepicker =
true;
532 ?
int $a_add_time = null,
533 ?array $a_custom_config = null,
534 ?
string $a_id2 = null,
535 ?array $a_custom_config2 = null,
536 ?
string $a_toggle_id = null,
537 ?
string $a_subform_id = null
541 $tpl = $DIC->ui()->mainTemplate();
542 foreach (self::getCodeForPicker(
551 $tpl->addOnLoadCode($code);
568 ?
int $a_add_time = null,
569 ?array $a_custom_config = null,
570 ?
string $a_id2 = null,
571 ?array $a_custom_config2 = null,
572 ?
string $a_toggle_id = null,
573 ?
string $a_subform_id = null
577 $ilUser = $DIC[
'ilUser'];
578 self::initDateTimePicker();
582 if ($ilUser->getLanguage() !=
'ar') {
583 $language = $ilUser->getLanguage();
586 'locale' => $language,
588 'useCurrent' =>
false,
589 'calendarWeeks' =>
true,
590 'toolbarPlacement' =>
'top',
594 'keepInvalid' =>
true,
595 'sideBySide' =>
true,
597 'format' => self::getUserDateFormat((
bool) $a_add_time)
600 $config = (!$a_custom_config)
602 : array_merge($default, $a_custom_config);
617 moment.updateLocale("' . $language .
'", {week: {dow: ' . $start_of_week .
'}}); 620 $code[] =
'$("#' . $a_id .
'").datetimepicker(' . json_encode($config) .
')';
624 $config2 = (!$a_custom_config2)
626 : array_merge($default, $a_custom_config2);
628 $config2[
"useCurrent"] =
false;
630 $code[] =
'$("#' . $a_id2 .
'").datetimepicker(' . json_encode($config2) .
')';
633 $code[] =
'il.Form.initDateDurationPicker("' . $a_id .
'","' . $a_id2 .
'","' . $a_toggle_id .
'","' . $a_subform_id .
'");';
634 } elseif ($a_subform_id) {
636 $code[] =
'il.Form.initDatePicker("' . $a_id .
'","' . $a_subform_id .
'");';
649 public static function parseDateString(
string $a_date,
bool $a_add_time =
false,
bool $a_use_generic_format =
false): array
653 $ilUser = $DIC[
'ilUser'];
654 if (!$a_use_generic_format) {
655 $out_format = self::getUserDateFormat($a_add_time,
true);
657 $out_format = $a_add_time
661 $tmp = date_parse_from_format($out_format, $a_date);
664 if (!$tmp[
"error_count"] &&
665 !$tmp[
"warning_count"]) {
666 $format = $tmp[
"year"] .
"-" .
667 str_pad($tmp[
"month"], 2,
"0", STR_PAD_LEFT) .
"-" .
668 str_pad($tmp[
"day"], 2,
"0", STR_PAD_LEFT);
672 str_pad($tmp[
"hour"], 2,
"0", STR_PAD_LEFT) .
":" .
673 str_pad($tmp[
"minute"], 2,
"0", STR_PAD_LEFT) .
":" .
674 str_pad($tmp[
"second"], 2,
"0", STR_PAD_LEFT);
685 "warnings" =>
sizeof($tmp[
"warnings"])
689 "errors" =>
sizeof($tmp[
"errors"])
706 } elseif (trim($a_value)) {
708 $parsed = self::parseDateString($a_value, $a_add_time);
709 if (is_object($parsed[
"date"])) {
710 return $parsed[
"date"];
713 $parsed = self::parseDateString($a_value, $a_add_time,
true);
714 if (is_object($parsed[
"date"])) {
715 return $parsed[
"date"];
static _getMaxDayOfMonth(int $a_year, int $a_month)
get max day of month 2008,2 => 29
static addDateTimePicker(string $a_id, ?int $a_add_time=null, ?array $a_custom_config=null, ?string $a_id2=null, ?array $a_custom_config2=null, ?string $a_toggle_id=null, ?string $a_subform_id=null)
Add date time picker to element.
static _buildMonthDayList(int $a_month, int $a_year, int $weekstart)
Build a month day list.
static convertDateToUtcDBTimestamp(\ilDateTime $date=null)
static initDateTimePicker()
static _numericMonthToString(int $a_month, bool $a_long=true)
numeric month to string
static parseDateString(string $a_date, bool $a_add_time=false, bool $a_use_generic_format=false)
Parse (incoming) string to date/time object.
get(int $a_format, string $a_format_str='', string $a_tz='')
static _buildWeekDayList(ilDate $a_day, int $a_weekstart)
build week day list public
static getZoneInfoFile($a_tz)
static bool $init_datetimepicker
Stores calendar categories.
static _getShortTimeZoneList()
get short timezone list
static getUserDateFormat(int $a_add_time=0, bool $a_for_parsing=false)
Parse current user setting into date/time format.
static getHourSelection(int $a_format)
Get hour selection depending on user specific hour format.
static _getInstanceByUserId(int $a_user_id)
static initDefaultCalendarByType(int $a_type_id, int $a_usr_id, string $a_title, bool $a_create=false)
Init the default calendar for given type and user.
static _isLeapYear(int $a_year)
check if a given year is a leap year
static array $default_calendar
static _numericDayToString(int $a_day, bool $a_long=true)
static calculateFontColor(string $a_html_color_code)
Calculate best font color from html hex color code.
static _equals(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
Check if two date are equal.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static parseIncomingDate($a_value, bool $a_add_time=false)
Try to parse incoming value to date object.
static getCodeForPicker(string $a_id, ?int $a_add_time=null, ?array $a_custom_config=null, ?string $a_id2=null, ?array $a_custom_config2=null, ?string $a_toggle_id=null, ?string $a_subform_id=null)
Add date time picker to element.
static _isToday(ilDateTime $date)