public function date($message, $viewmail = false) { $tz = core_date::get_user_timezone(); $date = new DateTime('now', new DateTimeZone($tz)); $offset = ($date->getOffset() - dst_offset_on(time(), $tz)) / (3600.0); $time = ($offset < 13) ? $message->time() + $offset : $message->time(); $now = ($offset < 13) ? time() + $offset : time(); $daysago = floor($now / 86400) - floor($time / 86400); $yearsago = (int) date('Y', $now) - (int) date('Y', $time); $tooltip = userdate($time, get_string('strftimedatetime')); if ($viewmail) { $content = userdate($time, get_string('strftimedatetime')); $tooltip = ''; } else if ($daysago == 0) { $content = userdate($time, get_string('strftimetime')); } else if ($yearsago == 0) { $content = userdate($time, get_string('strftimedateshort')); } else { $content = userdate($time, get_string('strftimedate')); } return html_writer::tag('span', s($content), array('class' => 'mail_date', 'title' => $tooltip)); }
function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_year = false) { global $CFG, $USER; $display = new stdClass(); $display->minwday = get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY); $display->maxwday = $display->minwday + 6; $content = ''; if (!empty($cal_month) && !empty($cal_year)) { $thisdate = usergetdate(time()); // Date and time the user sees at his location if ($cal_month == $thisdate['mon'] && $cal_year == $thisdate['year']) { // Navigated to this month $date = $thisdate; $display->thismonth = true; } else { // Navigated to other month, let's do a nice trick and save us a lot of work... if (!checkdate($cal_month, 1, $cal_year)) { $date = array('mday' => 1, 'mon' => $thisdate['mon'], 'year' => $thisdate['year']); $display->thismonth = true; } else { $date = array('mday' => 1, 'mon' => $cal_month, 'year' => $cal_year); $display->thismonth = false; } } } else { $date = usergetdate(time()); // Date and time the user sees at his location $display->thismonth = true; } // Fill in the variables we 're going to use, nice and tidy list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display $display->maxdays = calendar_days_in_month($m, $y); if (get_user_timezone_offset() < 99) { // We 'll keep these values as GMT here, and offset them when the time comes to query the db $display->tstart = gmmktime(0, 0, 0, $m, 1, $y); // This is GMT $display->tend = gmmktime(23, 59, 59, $m, $display->maxdays, $y); // GMT } else { // no timezone info specified $display->tstart = mktime(0, 0, 0, $m, 1, $y); $display->tend = mktime(23, 59, 59, $m, $display->maxdays, $y); } $startwday = dayofweek(1, $m, $y); // Align the starting weekday to fall in our display range // This is simple, not foolproof. if ($startwday < $display->minwday) { $startwday += 7; } // TODO: THIS IS TEMPORARY CODE! // [pj] I was just reading through this and realized that I when writing this code I was probably // asking for trouble, as all these time manipulations seem to be unnecessary and a simple // make_timestamp would accomplish the same thing. So here goes a test: //$test_start = make_timestamp($y, $m, 1); //$test_end = make_timestamp($y, $m, $display->maxdays, 23, 59, 59); //if($test_start != usertime($display->tstart) - dst_offset_on($display->tstart)) { //notify('Failed assertion in calendar/lib.php line 126; display->tstart = '.$display->tstart.', dst_offset = '.dst_offset_on($display->tstart).', usertime = '.usertime($display->tstart).', make_t = '.$test_start); //} //if($test_end != usertime($display->tend) - dst_offset_on($display->tend)) { //notify('Failed assertion in calendar/lib.php line 130; display->tend = '.$display->tend.', dst_offset = '.dst_offset_on($display->tend).', usertime = '.usertime($display->tend).', make_t = '.$test_end); //} // Get the events matching our criteria. Don't forget to offset the timestamps for the user's TZ! $events = calendar_get_events(usertime($display->tstart) - dst_offset_on($display->tstart), usertime($display->tend) - dst_offset_on($display->tend), $users, $groups, $courses); // Set event course class for course events if (!empty($events)) { foreach ($events as $eventid => $event) { if (!empty($event->modulename)) { $cm = get_coursemodule_from_instance($event->modulename, $event->instance); if (!groups_course_module_visible($cm)) { unset($events[$eventid]); } } } } // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra // arguments to this function. $morehref = ''; if (!empty($courses)) { $courses = array_diff($courses, array(SITEID)); if (count($courses) == 1) { $morehref = '&course=' . reset($courses); } } // We want to have easy access by day, since the display is on a per-day basis. // Arguments passed by reference. //calendar_events_by_day($events, $display->tstart, $eventsbyday, $durationbyday, $typesbyday); calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses); //Accessibility: added summary and <abbr> elements. ///global $CALENDARDAYS; appears to be broken. $days_title = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); $summary = get_string('calendarheading', 'calendar', userdate(make_timestamp($y, $m), get_string('strftimemonthyear'))); $summary = get_string('tabledata', 'access', $summary); $content .= '<table class="minicalendar" summary="' . $summary . '">'; // Begin table $content .= '<tr class="weekdays">'; // Header row: day names // Print out the names of the weekdays $days = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'); for ($i = $display->minwday; $i <= $display->maxwday; ++$i) { // This uses the % operator to get the correct weekday no matter what shift we have // applied to the $display->minwday : $display->maxwday range from the default 0 : 6 $content .= '<th scope="col"><abbr title="' . get_string($days_title[$i % 7], 'calendar') . '">' . get_string($days[$i % 7], 'calendar') . "</abbr></th>\n"; } $content .= '</tr><tr>'; // End of day names; prepare for day numbers // For the table display. $week is the row; $dayweek is the column. $dayweek = $startwday; // Paddding (the first week may have blank days in the beginning) for ($i = $display->minwday; $i < $startwday; ++$i) { $content .= '<td class="dayblank"> </td>' . "\n"; } // Now display all the calendar for ($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) { if ($dayweek > $display->maxwday) { // We need to change week (table row) $content .= '</tr><tr>'; $dayweek = $display->minwday; } // Reset vars $cell = ''; if (CALENDAR_WEEKEND & 1 << $dayweek % 7) { // Weekend. This is true no matter what the exact range is. $class = 'weekend day'; } else { // Normal working day. $class = 'day'; } // Special visual fx if an event is defined if (isset($eventsbyday[$day])) { $dayhref = calendar_get_link_href(CALENDAR_URL . 'view.php?view=day' . $morehref . '&', $day, $m, $y); // OverLib popup $popupcontent = ''; foreach ($eventsbyday[$day] as $eventid) { if (!isset($events[$eventid])) { continue; } $event = $events[$eventid]; if (!empty($event->modulename)) { $popupicon = $CFG->modpixpath . '/' . $event->modulename . '/icon.gif'; $popupalt = $event->modulename; } else { if ($event->courseid == SITEID) { // Site event $popupicon = $CFG->pixpath . '/c/site.gif'; $popupalt = ''; } else { if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) { // Course event $popupicon = $CFG->pixpath . '/c/course.gif'; $popupalt = ''; } else { if ($event->groupid) { // Group event $popupicon = $CFG->pixpath . '/c/group.gif'; $popupalt = ''; } else { if ($event->userid) { // User event $popupicon = $CFG->pixpath . '/c/user.gif'; $popupalt = ''; } } } } } $popupcontent .= '<div><img class="icon" src="' . $popupicon . '" alt="' . $popupalt . '" /><a href="' . $dayhref . '#event_' . $event->id . '">' . format_string($event->name, true) . '</a></div>'; } //Accessibility: functionality moved to calendar_get_popup. if ($display->thismonth && $day == $d) { $popup = calendar_get_popup(true, $events[$eventid]->timestart, $popupcontent); } else { $popup = calendar_get_popup(false, $events[$eventid]->timestart, $popupcontent); } // Class and cell content if (isset($typesbyday[$day]['startglobal'])) { $class .= ' event_global'; } else { if (isset($typesbyday[$day]['startcourse'])) { $class .= ' event_course'; } else { if (isset($typesbyday[$day]['startgroup'])) { $class .= ' event_group'; } else { if (isset($typesbyday[$day]['startuser'])) { $class .= ' event_user'; } } } } $cell = '<a href="' . $dayhref . '" ' . $popup . '>' . $day . '</a>'; } else { $cell = $day; } if (isset($typesbyday[$day]['durationglobal'])) { $class .= ' duration_global'; } else { if (isset($typesbyday[$day]['durationcourse'])) { $class .= ' duration_course'; } else { if (isset($typesbyday[$day]['durationgroup'])) { $class .= ' duration_group'; } else { if (isset($typesbyday[$day]['durationuser'])) { $class .= ' duration_user'; } } } } // If event has a class set then add it to the table day <td> tag // Note: only one colour for minicalendar if (isset($eventsbyday[$day])) { foreach ($eventsbyday[$day] as $eventid) { if (!isset($events[$eventid])) { continue; } $event = $events[$eventid]; if (!empty($event->class)) { $class .= ' ' . $event->class; } break; } } // Special visual fx for today //Accessibility: hidden text for today, and popup. if ($display->thismonth && $day == $d) { $class .= ' today'; $today = get_string('today', 'calendar') . ' ' . userdate(time(), get_string('strftimedayshort')); if (!isset($eventsbyday[$day])) { $class .= ' eventnone'; $popup = calendar_get_popup(true, false); $cell = '<a href="#" ' . $popup . '>' . $day . '</a>'; } $cell = get_accesshide($today . ' ') . $cell; } // Just display it if (!empty($class)) { $class = ' class="' . $class . '"'; } $content .= '<td' . $class . '>' . $cell . "</td>\n"; } // Paddding (the last week may have blank days at the end) for ($i = $dayweek; $i <= $display->maxwday; ++$i) { $content .= '<td class="dayblank"> </td>'; } $content .= '</tr>'; // Last row ends $content .= '</table>'; // Tabular display of days ends return $content; }
/** * Function to convert time in user's timezone to GMT * Note: Moodle function usertime() doesn't include DST offset * @param int $usertime timestamp in user's timezone * @param float|int|string $timezone optional timezone to use, defaults to user's * @return int timestamp in GMT */ function pm_gmt_from_usertime($usertime, $timezone = 99) { $tz = get_user_timezone_offset($timezone); if (abs($tz) > 13) { return $usertime; } $usertime -= (int) ($tz * HOURSECS); if ($timezone == 99 || !is_numeric($timezone)) { $usertime -= dst_offset_on($usertime, $timezone); } return $usertime; }
/** * Update or create an event within the database * * Pass in a object containing the event properties and this function will * insert it into the database and deal with any associated files * * @see add_event() * @see update_event() * * @param stdClass $data object of event * @param bool $checkcapability if moodle should check calendar managing capability or not * @return bool event updated */ public function update($data, $checkcapability = true) { global $CFG, $DB, $USER; foreach ($data as $key => $value) { $this->properties->{$key} = $value; } $this->properties->timemodified = time(); $usingeditor = !empty($this->properties->description) && is_array($this->properties->description); if (empty($this->properties->id) || $this->properties->id < 1) { if ($checkcapability) { if (!calendar_add_event_allowed($this->properties)) { print_error('nopermissiontoupdatecalendar'); } } if ($usingeditor) { switch ($this->properties->eventtype) { case 'user': $this->properties->courseid = 0; $this->properties->course = 0; $this->properties->groupid = 0; $this->properties->userid = $USER->id; break; case 'site': $this->properties->courseid = SITEID; $this->properties->course = SITEID; $this->properties->groupid = 0; $this->properties->userid = $USER->id; break; case 'course': $this->properties->groupid = 0; $this->properties->userid = $USER->id; break; case 'group': $this->properties->userid = $USER->id; break; default: // Ewww we should NEVER get here, but just incase we do lets // fail gracefully $usingeditor = false; break; } // If we are actually using the editor, we recalculate the context because some default values // were set when calculate_context() was called from the constructor. if ($usingeditor) { $this->properties->context = $this->calculate_context($this->properties); $this->editorcontext = $this->properties->context; } $editor = $this->properties->description; $this->properties->format = $this->properties->description['format']; $this->properties->description = $this->properties->description['text']; } // Insert the event into the database $this->properties->id = $DB->insert_record('event', $this->properties); if ($usingeditor) { $this->properties->description = file_save_draft_area_files($editor['itemid'], $this->editorcontext->id, 'calendar', 'event_description', $this->properties->id, $this->editoroptions, $editor['text'], $this->editoroptions['forcehttps']); $DB->set_field('event', 'description', $this->properties->description, array('id' => $this->properties->id)); } // Log the event entry. add_to_log($this->properties->courseid, 'calendar', 'add', 'event.php?action=edit&id=' . $this->properties->id, $this->properties->name); $repeatedids = array(); if (!empty($this->properties->repeat)) { $this->properties->repeatid = $this->properties->id; $DB->set_field('event', 'repeatid', $this->properties->repeatid, array('id' => $this->properties->id)); $eventcopy = clone $this->properties; unset($eventcopy->id); for ($i = 1; $i < $eventcopy->repeats; $i++) { $eventcopy->timestart = $eventcopy->timestart + WEEKSECS + dst_offset_on($eventcopy->timestart) - dst_offset_on($eventcopy->timestart + WEEKSECS); // Get the event id for the log record. $eventcopyid = $DB->insert_record('event', $eventcopy); // If the context has been set delete all associated files if ($usingeditor) { $fs = get_file_storage(); $files = $fs->get_area_files($this->editorcontext->id, 'calendar', 'event_description', $this->properties->id); foreach ($files as $file) { $fs->create_file_from_storedfile(array('itemid' => $eventcopyid), $file); } } $repeatedids[] = $eventcopyid; // Log the event entry. add_to_log($eventcopy->courseid, 'calendar', 'add', 'event.php?action=edit&id=' . $eventcopyid, $eventcopy->name); } } // Hook for tracking added events self::calendar_event_hook('add_event', array($this->properties, $repeatedids)); return true; } else { if ($checkcapability) { if (!calendar_edit_event_allowed($this->properties)) { print_error('nopermissiontoupdatecalendar'); } } if ($usingeditor) { if ($this->editorcontext !== null) { $this->properties->description = file_save_draft_area_files($this->properties->description['itemid'], $this->editorcontext->id, 'calendar', 'event_description', $this->properties->id, $this->editoroptions, $this->properties->description['text'], $this->editoroptions['forcehttps']); } else { $this->properties->format = $this->properties->description['format']; $this->properties->description = $this->properties->description['text']; } } $event = $DB->get_record('event', array('id' => $this->properties->id)); $updaterepeated = !empty($this->properties->repeatid) && !empty($this->properties->repeateditall); if ($updaterepeated) { // Update all if ($this->properties->timestart != $event->timestart) { $timestartoffset = $this->properties->timestart - $event->timestart; $sql = "UPDATE {event}\n SET name = ?,\n description = ?,\n timestart = timestart + ?,\n timeduration = ?,\n timemodified = ?\n WHERE repeatid = ?"; $params = array($this->properties->name, $this->properties->description, $timestartoffset, $this->properties->timeduration, time(), $event->repeatid); } else { $sql = "UPDATE {event} SET name = ?, description = ?, timeduration = ?, timemodified = ? WHERE repeatid = ?"; $params = array($this->properties->name, $this->properties->description, $this->properties->timeduration, time(), $event->repeatid); } $DB->execute($sql, $params); // Log the event update. add_to_log($this->properties->courseid, 'calendar', 'edit all', 'event.php?action=edit&id=' . $this->properties->id, $this->properties->name); } else { $DB->update_record('event', $this->properties); $event = calendar_event::load($this->properties->id); $this->properties = $event->properties(); add_to_log($this->properties->courseid, 'calendar', 'edit', 'event.php?action=edit&id=' . $this->properties->id, $this->properties->name); } // Hook for tracking event updates self::calendar_event_hook('update_event', array($this->properties, $updaterepeated)); return true; } }
/** * Given a GMT timestamp (seconds since epoch), offsets it by * the timezone. eg 3pm in India is 3pm GMT - 7 * 3600 seconds * * NOTE: this function does not include DST properly, * you should use the PHP date stuff instead! * * @package core * @category time * @param int $date Timestamp in GMT * @param float|int|string $timezone user timezone * @return int */ function usertime($date, $timezone = 99) { $userdate = new DateTime('@' . $date); $userdate->setTimezone(core_date::get_user_timezone_object($timezone)); $dst = dst_offset_on($date, $timezone); return $date - $userdate->getOffset() + $dst; }
$eventid = insert_record('event', $form, true); /// Use the event id as the repeatid to link repeat entries together if ($form->repeat) { $form->repeatid = $form->id = $eventid; update_record('event', $form); // update the row, to set its repeatid } /// Log the event entry. add_to_log($form->courseid, 'calendar', 'add', 'event.php?action=edit&id=' . $eventid, stripslashes($form->name)); if ($form->repeat) { for ($i = 1; $i < $form->repeats; $i++) { // What's the DST offset for the previous repeat? $dst_offset_prev = dst_offset_on($form->timestart); $form->timestart += WEEKSECS; // If the offset has changed in the meantime, update this repeat accordingly $form->timestart += $dst_offset_prev - dst_offset_on($form->timestart); /// Get the event id for the log record. $eventid = insert_record('event', $form, true); /// Log the event entry. add_to_log($form->courseid, 'calendar', 'add', 'event.php?action=edit&id=' . $eventid, stripslashes($form->name)); } } // OK, now redirect to day view redirect(CALENDAR_URL . 'view.php?view=day&course=' . $urlcourse . '&cal_d=' . $form->startday . '&cal_m=' . $form->startmon . '&cal_y=' . $form->startyr); } else { foreach ($err as $key => $value) { $focus = 'form.' . $key; } } } break;
/** * Calculates the Daylight Saving Offset for a given date/time (timestamp) * - Note: Daylight saving only works for string timezones and not for float. * * @package core * @category time * @param int $time must NOT be compensated at all, it has to be a pure timestamp * @param int|float|string $strtimezone timezone for which offset is expected, if 99 or null * then user's default timezone is used. {@link http://docs.moodle.org/dev/Time_API#Timezone} * @return int */ function dst_offset_on($time, $strtimezone = null) { global $SESSION; if (!calculate_user_dst_table(null, null, $strtimezone) || empty($SESSION->dst_offsets)) { return 0; } reset($SESSION->dst_offsets); while (list($from, $offset) = each($SESSION->dst_offsets)) { if ($from <= $time) { break; } } // This is the normal return path. if ($offset !== null) { return $offset; } // Reaching this point means we haven't calculated far enough, do it now: // Calculate extra DST changes if needed and recurse. The recursion always // moves toward the stopping condition, so will always end. if ($from == 0) { // We need a year smaller than $SESSION->dst_range[0]. if ($SESSION->dst_range[0] == 1971) { return 0; } calculate_user_dst_table($SESSION->dst_range[0] - 5, null, $strtimezone); return dst_offset_on($time, $strtimezone); } else { // We need a year larger than $SESSION->dst_range[1]. if ($SESSION->dst_range[1] == 2035) { return 0; } calculate_user_dst_table(null, $SESSION->dst_range[1] + 5, $strtimezone); return dst_offset_on($time, $strtimezone); } }
public function test_dst_offset_on() { $time = gmmktime(1, 1, 1, 3, 1, 2015); $this->assertSame(3600, dst_offset_on($time, 'Pacific/Auckland')); $this->assertSame(0, dst_offset_on($time, 'Australia/Perth')); $this->assertSame(1800, dst_offset_on($time, 'Australia/Lord_Howe')); $this->assertSame(0, dst_offset_on($time, 'Europe/Prague')); $this->assertSame(0, dst_offset_on($time, 'America/New_York')); $time = gmmktime(1, 1, 1, 5, 1, 2015); $this->assertSame(0, dst_offset_on($time, 'Pacific/Auckland')); $this->assertSame(0, dst_offset_on($time, 'Australia/Perth')); $this->assertSame(0, dst_offset_on($time, 'Australia/Lord_Howe')); $this->assertSame(3600, dst_offset_on($time, 'Europe/Prague')); $this->assertSame(3600, dst_offset_on($time, 'America/New_York')); }
/** * Returns an int which represents the systems's timezone difference from GMT in seconds * @deprecated since Moodle 2.9 * @param float|int|string $tz timezone for which offset is required. * {@link http://docs.moodle.org/dev/Time_API#Timezone} * @return int|bool if found, false is timezone 99 or error */ function get_timezone_offset($tz) { debugging('get_timezone_offset() is deprecated, use PHP DateTimeZone instead', DEBUG_DEVELOPER); $date = new DateTime('now', new DateTimeZone(core_date::normalise_timezone($tz))); return $date->getOffset() - dst_offset_on(time(), $tz); }
/** * This function converts a timestamp in timezone to GMT (UTC) * @param $timestamp * @param $timezone * @param mixed $dstdate default null uses $timestamp (param1) for dst calc * false disables dst offset, * otherwise dstdate value used in place of timestamp for dst calc * @return int adjusted timestamp (secs since epoch) */ function to_gmt($timestamp, $timezone = 99, $dstdate = null) { if ($dstdate == null) { $dstdate = $timestamp; } $ts = $timestamp; $dstoffset = null; if (!empty($dstdate) && ($timezone == 99 || !is_numeric($timezone))) { $strtimezone = is_numeric($timezone) ? NULL : $timezone; $dstoffset = dst_offset_on($dstdate, $strtimezone); $ts -= $dstoffset; // or += see to_gmt() } $tz = get_user_timezone_offset($timezone); $ts = abs($tz) > 13 ? $ts : $ts - $tz * HOURSECS; //debug_error_log("/blocks/php_report/sharedlib.php::to_gmt({$timestamp}, {$timezone}): tz = {$tz} dstdate = {$dstdate} dstoffset = {$dstoffset} => $ts"); return $ts; }
require_once $CFG->dirroot . '/mod/hotpot/locallib.php'; // admin_setting_xxx classes are defined in "lib/adminlib.php" // new admin_setting_configcheckbox($name, $visiblename, $description, $defaultsetting); // show Quizports on MyMoodle page (default=1) $settings->add(new admin_setting_configcheckbox('hotpot_enablemymoodle', get_string('enablemymoodle', 'mod_hotpot'), get_string('configenablemymoodle', 'mod_hotpot'), 1)); // enable caching of browser content for each quiz (default=1) $str = get_string('clearcache', 'mod_hotpot'); $url = new moodle_url('/mod/hotpot/tools/clear_cache.php', array('sesskey' => sesskey())); $link = html_writer::link($url, $str, array('class' => 'small', 'style' => 'white-space: nowrap', 'onclick' => "this.target='_blank'")) . "\n"; $settings->add(new admin_setting_configcheckbox('hotpot_enablecache', get_string('enablecache', 'mod_hotpot'), get_string('configenablecache', 'mod_hotpot') . ' ' . $link, 1)); // restrict cron job to certain hours of the day (default=never) if (class_exists('core_date') && method_exists('core_date', 'get_user_timezone')) { // Moodle >= 2.9 $timezone = core_date::get_user_timezone(99); $datetime = new DateTime('now', new DateTimeZone($timezone)); $timezone = ($datetime->getOffset() - dst_offset_on(time(), $timezone)) / 3600.0; } else { // Moodle <= 2.8 $timezone = get_user_timezone_offset(); } if (abs($timezone) > 13) { $timezone = 0; } else { if ($timezone > 0) { $timezone = $timezone - 24; } } $options = array(); for ($i = 0; $i <= 23; $i++) { $options[($i - $timezone) % 24] = gmdate('H:i', $i * HOURSECS); }
/** * Returns a formatted string that represents a date in user time. * * Returns a formatted string that represents a date in user time * <b>WARNING: note that the format is for strftime(), not date().</b> * Because of a bug in most Windows time libraries, we can't use * the nicer %e, so we have to use %d which has leading zeroes. * A lot of the fuss in the function is just getting rid of these leading * zeroes as efficiently as possible. * * If parameter fixday = true (default), then take off leading * zero from %d, else maintain it. * * @param int $time the timestamp in UTC, as obtained from the database * @param string $format strftime format * @param int|float|string $timezone the timezone to use * {@link http://docs.moodle.org/dev/Time_API#Timezone} * @param bool $fixday if true then the leading zero from %d is removed, * if false then the leading zero is maintained * @param bool $fixhour if true then the leading zero from %I is removed, * if false then the leading zero is maintained * @return string the formatted date/time */ public function timestamp_to_date_string($time, $format, $timezone, $fixday, $fixhour) { global $CFG; if (empty($format)) { $format = get_string('strftimedaydatetime', 'langconfig'); } if (!empty($CFG->nofixday)) { // Config.php can force %d not to be fixed. $fixday = false; } else { if ($fixday) { $formatnoday = str_replace('%d', 'DD', $format); $fixday = $formatnoday != $format; $format = $formatnoday; } } // Note: This logic about fixing 12-hour time to remove unnecessary leading // zero is required because on Windows, PHP strftime function does not // support the correct 'hour without leading zero' parameter (%l). if (!empty($CFG->nofixhour)) { // Config.php can force %I not to be fixed. $fixhour = false; } else { if ($fixhour) { $formatnohour = str_replace('%I', 'HH', $format); $fixhour = $formatnohour != $format; $format = $formatnohour; } } // Add daylight saving offset for string timezones only, as we can't get dst for // float values. if timezone is 99 (user default timezone), then try update dst. if (99 == $timezone || !is_numeric($timezone)) { $time += dst_offset_on($time, $timezone); } $timezone = get_user_timezone_offset($timezone); // If we are running under Windows convert to windows encoding and then back to UTF-8 // (because it's impossible to specify UTF-8 to fetch locale info in Win32). if (abs($timezone) > 13) { // Server time. $datestring = date_format_string($time, $format, $timezone); if ($fixday) { $daystring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %d', $time))); $datestring = str_replace('DD', $daystring, $datestring); } if ($fixhour) { $hourstring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %I', $time))); $datestring = str_replace('HH', $hourstring, $datestring); } } else { $time += (int) ($timezone * 3600); $datestring = date_format_string($time, $format, $timezone); if ($fixday) { $daystring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %d', $time))); $datestring = str_replace('DD', $daystring, $datestring); } if ($fixhour) { $hourstring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %I', $time))); $datestring = str_replace('HH', $hourstring, $datestring); } } return $datestring; }