Merge branch 'MDL-41792_master' of https://github.com/markn86/moodle
[moodle.git] / calendar / type / gregorian / classes / structure.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 namespace calendartype_gregorian;
18 use core_calendar\type_base;
20 /**
21  * Handles calendar functions for the gregorian calendar.
22  *
23  * @package calendartype_gregorian
24  * @copyright 2008 onwards Foodle Group {@link http://foodle.org}
25  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
27 class structure extends type_base {
29     /**
30      * Returns the name of the calendar.
31      *
32      * This is the non-translated name, usually just
33      * the name of the folder.
34      *
35      * @return string the calendar name
36      */
37     public function get_name() {
38         return 'gregorian';
39     }
41     /**
42      * Returns a list of all the possible days for all months.
43      *
44      * This is used to generate the select box for the days
45      * in the date selector elements. Some months contain more days
46      * than others so this function should return all possible days as
47      * we can not predict what month will be chosen (the user
48      * may have JS turned off and we need to support this situation in
49      * Moodle).
50      *
51      * @return array the days
52      */
53     public function get_days() {
54         $days = array();
56         for ($i = 1; $i <= 31; $i++) {
57             $days[$i] = $i;
58         }
60         return $days;
61     }
63     /**
64      * Returns a list of all the names of the months.
65      *
66      * @return array the month names
67      */
68     public function get_months() {
69         $months = array();
71         for ($i = 1; $i <= 12; $i++) {
72             $months[$i] = userdate(gmmktime(12, 0, 0, $i, 15, 2000), '%B');
73         }
75         return $months;
76     }
78     /**
79      * Returns the minimum year of the calendar.
80      *
81      * @return int the minumum year
82      */
83     public function get_min_year() {
84         return 1900;
85     }
87     /**
88      * Returns the maximum year of the calendar.
89      *
90      * @return int the max year
91      */
92     public function get_max_year() {
93         return 2050;
94     }
96     /**
97      * Returns the number of days in a week.
98      *
99      * @return int the number of days
100      */
101     public function get_num_weekdays() {
102         return 7;
103     }
105     /**
106      * Returns an indexed list of all the names of the weekdays.
107      *
108      * The list starts with the index 0. Each index, representing a
109      * day, must be an array that contains the indexes 'shortname'
110      * and 'fullname'.
111      *
112      * @return array array of days
113      */
114     public function get_weekdays() {
115         return array(
116             0 => array(
117                 'shortname' => get_string('sun', 'calendar'),
118                 'fullname' => get_string('sunday', 'calendar')
119             ),
120             1 => array(
121                 'shortname' => get_string('mon', 'calendar'),
122                 'fullname' => get_string('monday', 'calendar')
123             ),
124             2 => array(
125                 'shortname' => get_string('tue', 'calendar'),
126                 'fullname' => get_string('tuesday', 'calendar')
127             ),
128             3 => array(
129                 'shortname' => get_string('wed', 'calendar'),
130                 'fullname' => get_string('wednesday', 'calendar')
131             ),
132             4 => array(
133                 'shortname' => get_string('thu', 'calendar'),
134                 'fullname' => get_string('thursday', 'calendar')
135             ),
136             5 => array(
137                 'shortname' => get_string('fri', 'calendar'),
138                 'fullname' => get_string('friday', 'calendar')
139             ),
140             6 => array(
141                 'shortname' => get_string('sat', 'calendar'),
142                 'fullname' => get_string('saturday', 'calendar')
143             ),
144         );
145     }
147     /**
148      * Returns the index of the starting week day.
149      *
150      * This may vary, for example some may consider Monday as the start of the week,
151      * where as others may consider Sunday the start.
152      *
153      * @return int
154      */
155     public function get_starting_weekday() {
156         global $CFG;
158         if (isset($CFG->calendar_startwday)) {
159             $firstday = $CFG->calendar_startwday;
160         } else {
161             $firstday = get_string('firstdayofweek', 'langconfig');
162         }
164         if (!is_numeric($firstday)) {
165             $startingweekday = CALENDAR_DEFAULT_STARTING_WEEKDAY;
166         } else {
167             $startingweekday = intval($firstday) % 7;
168         }
170         return get_user_preferences('calendar_startwday', $startingweekday);
171     }
173     /**
174      * Returns the index of the weekday for a specific calendar date.
175      *
176      * @param int $year
177      * @param int $month
178      * @param int $day
179      * @return int
180      */
181     public function get_weekday($year, $month, $day) {
182         return intval(date('w', mktime(12, 0, 0, $month, $day, $year)));
183     }
185     /**
186      * Returns the number of days in a given month.
187      *
188      * @param int $year
189      * @param int $month
190      * @return int the number of days
191      */
192     public function get_num_days_in_month($year, $month) {
193         return intval(date('t', mktime(0, 0, 0, $month, 1, $year)));
194     }
196     /**
197      * Get the previous month.
198      *
199      * If the current month is January, it will get the last month of the previous year.
200      *
201      * @param int $year
202      * @param int $month
203      * @return array previous month and year
204      */
205     public function get_prev_month($year, $month) {
206         if ($month == 1) {
207             return array(12, $year - 1);
208         } else {
209             return array($month - 1, $year);
210         }
211     }
213     /**
214      * Get the next month.
215      *
216      * If the current month is December, it will get the first month of the following year.
217      *
218      * @param int $year
219      * @param int $month
220      * @return array the following month and year
221      */
222     public function get_next_month($year, $month) {
223         if ($month == 12) {
224             return array(1, $year + 1);
225         } else {
226             return array($month + 1, $year);
227         }
228     }
230     /**
231      * Returns a formatted string that represents a date in user time.
232      *
233      * Returns a formatted string that represents a date in user time
234      * <b>WARNING: note that the format is for strftime(), not date().</b>
235      * Because of a bug in most Windows time libraries, we can't use
236      * the nicer %e, so we have to use %d which has leading zeroes.
237      * A lot of the fuss in the function is just getting rid of these leading
238      * zeroes as efficiently as possible.
239      *
240      * If parameter fixday = true (default), then take off leading
241      * zero from %d, else maintain it.
242      *
243      * @param int $time the timestamp in UTC, as obtained from the database
244      * @param string $format strftime format
245      * @param int|float|string $timezone the timezone to use
246      *        {@link http://docs.moodle.org/dev/Time_API#Timezone}
247      * @param bool $fixday if true then the leading zero from %d is removed,
248      *        if false then the leading zero is maintained
249      * @param bool $fixhour if true then the leading zero from %I is removed,
250      *        if false then the leading zero is maintained
251      * @return string the formatted date/time
252      */
253     public function timestamp_to_date_string($time, $format, $timezone, $fixday, $fixhour) {
254         global $CFG;
256         if (empty($format)) {
257             $format = get_string('strftimedaydatetime', 'langconfig');
258         }
260         if (!empty($CFG->nofixday)) { // Config.php can force %d not to be fixed.
261             $fixday = false;
262         } else if ($fixday) {
263             $formatnoday = str_replace('%d', 'DD', $format);
264             $fixday = ($formatnoday != $format);
265             $format = $formatnoday;
266         }
268         // Note: This logic about fixing 12-hour time to remove unnecessary leading
269         // zero is required because on Windows, PHP strftime function does not
270         // support the correct 'hour without leading zero' parameter (%l).
271         if (!empty($CFG->nofixhour)) {
272             // Config.php can force %I not to be fixed.
273             $fixhour = false;
274         } else if ($fixhour) {
275             $formatnohour = str_replace('%I', 'HH', $format);
276             $fixhour = ($formatnohour != $format);
277             $format = $formatnohour;
278         }
280         // Add daylight saving offset for string timezones only, as we can't get dst for
281         // float values. if timezone is 99 (user default timezone), then try update dst.
282         if ((99 == $timezone) || !is_numeric($timezone)) {
283             $time += dst_offset_on($time, $timezone);
284         }
286         $timezone = get_user_timezone_offset($timezone);
288         // If we are running under Windows convert to windows encoding and then back to UTF-8
289         // (because it's impossible to specify UTF-8 to fetch locale info in Win32).
290         if (abs($timezone) > 13) { // Server time.
291             $datestring = date_format_string($time, $format, $timezone);
292             if ($fixday) {
293                 $daystring  = ltrim(str_replace(array(' 0', ' '), '', strftime(' %d', $time)));
294                 $datestring = str_replace('DD', $daystring, $datestring);
295             }
296             if ($fixhour) {
297                 $hourstring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %I', $time)));
298                 $datestring = str_replace('HH', $hourstring, $datestring);
299             }
300         } else {
301             $time += (int)($timezone * 3600);
302             $datestring = date_format_string($time, $format, $timezone);
303             if ($fixday) {
304                 $daystring  = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %d', $time)));
305                 $datestring = str_replace('DD', $daystring, $datestring);
306             }
307             if ($fixhour) {
308                 $hourstring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %I', $time)));
309                 $datestring = str_replace('HH', $hourstring, $datestring);
310             }
311         }
313         return $datestring;
314     }
316     /**
317      * Given a $time timestamp in GMT (seconds since epoch), returns an array that
318      * represents the date in user time.
319      *
320      * @param int $time Timestamp in GMT
321      * @param float|int|string $timezone offset's time with timezone, if float and not 99, then no
322      *        dst offset is applied {@link http://docs.moodle.org/dev/Time_API#Timezone}
323      * @return array an array that represents the date in user time
324      */
325     public function timestamp_to_date_array($time, $timezone = 99) {
326         return usergetdate($time, $timezone);
327     }
329     /**
330      * Provided with a day, month, year, hour and minute in a specific
331      * calendar type convert it into the equivalent Gregorian date.
332      *
333      * In this function we don't need to do anything except pass the data
334      * back as an array. This is because the date received is Gregorian.
335      *
336      * @param int $year
337      * @param int $month
338      * @param int $day
339      * @param int $hour
340      * @param int $minute
341      * @return array the converted date
342      */
343     public function convert_from_gregorian($year, $month, $day, $hour = 0, $minute = 0) {
344         $date = array();
345         $date['year'] = $year;
346         $date['month'] = $month;
347         $date['day'] = $day;
348         $date['hour'] = $hour;
349         $date['minute'] = $minute;
351         return $date;
352     }
354     /**
355      * Provided with a day, month, year, hour and minute in a specific
356      * calendar type convert it into the equivalent Gregorian date.
357      *
358      * In this function we don't need to do anything except pass the data
359      * back as an array. This is because the date received is Gregorian.
360      *
361      * @param int $year
362      * @param int $month
363      * @param int $day
364      * @param int $hour
365      * @param int $minute
366      * @return array the converted date
367      */
368     public function convert_to_gregorian($year, $month, $day, $hour = 0, $minute = 0) {
369         $date = array();
370         $date['year'] = $year;
371         $date['month'] = $month;
372         $date['day'] = $day;
373         $date['hour'] = $hour;
374         $date['minute'] = $minute;
376         return $date;
377     }