Internally Moodle always stores all times in unixtime format (number of seconds since epoch) which is independent of timezones.
The Time API is used to display proper date-time depending on user or site timezones.
There is a class in Moodle to handle most needs of working with times. There are 2 cases to consider when working with time:
This is when you are dealing with dates on the server e.g. executing scheduled tasks, performing background tasks - anything which does not depend on the timezone of any specific user.
This is when you are manipulating dates and times and you need to display them to the user in their current timezone (which may be different for each user).
The main API for time is in the class "core_date" which will give you php DateTimeZone objects for either user time or server time as needed. You can then use the php datetime classes to manipulate the time. When finished manipulating the time, get a timestamp with DateTime::getTimestamp().
Example: Get the current server time + 1 day.
$tomorrow = new DateTime("1 day", core_date::get_server_timezone_object());
Get a timestamp for storing in the database:
$tomorrowint = $tomorrow->getTimestamp();
Get a timestamp for 3pm tomorrow in the current users timezone.
$time = new DateTime("now", core_date::get_user_timezone_object()); $time->add(new DateInterval("P1D")); $time->setTime(15, 0, 0); $timestamp = $time->getTimestamp();
Remember! NEVER NEVER NEVER add or subtract timestamps for any reason - you will get it wrong (DST is a killer)!
Other functions related to time api can be found in lib/moodlelib.php.
- Time API's for current user
- make_timestamp - Given date-time, it produces a GMT timestamp for current user.
- userdate - Gets formatted string that represents a date in user time (note that the format required by this function is the strftime() format, not the more common format used by date())
- usertime - Given a GMT timestamp (seconds since epoch), offsets it by the timezone. eg 3pm in India is 3pm GMT - 5.5 * 3600 seconds
- usergetdate - Given a timestamp in GMT, returns an array that represents the date-time in user time
- usergetmidnight - Given a date, return the GMT timestamp of the most recent midnight for the current user.
- usertimezone - Returns current user's timezone
- System Time API
- format_time - Format a date/time (seconds) as weeks, days, hours etc as needed
- dst_offset_on - Calculates the Daylight Saving Offset for a given date/time (timestamp)
- find_day_in_month - Calculates when the day appears in specific month
- days_in_month - Calculate number of days in a given month
- dayofweek - Calculate the position in the week of a specific calendar day
- Older legacy date/time functions. Do not use in new code.
- usertime - Appends the users timezone offset to an integer timestamp
- get_timezone_offset - Systems's timezone difference from GMT in seconds
- get_user_timezone_offset - Returns user's timezone difference from GMT in hours
- dst_changes_for_year - Calculates the required DST change and returns a Timestamp Array
Moodle supports following timezone formats:
- UTC (specifically UTC−11 to UTC+11)
- Time offsets from UTC (int +-(0-13) or float +-(0.5-12.5))
- World timezones (Australia/Perth)
Timezone depends on en:Location of the user and can be forced upon by administrator.
DST is abbreviation of Day light saving. Many countries, and sometimes just certain regions of countries, adopt daylight saving time (also known as "Summer Time") during part of the year. Moodle automatically calculates DST for current user, depending on user location.
Time API's for current user
Prints a formatted date in user time
// Get current day, month and year for current user. $date = new DateTime("now", core_date::get_user_timezone_object()); $date->setTime(0, 0, 0); // Print formatted date in user time. echo userdate($date->getTimestamp(), "Current user time");
System Time API
Find the day of the week for the first day in this month.
$now = new DateTime("now", core_date::get_server_timezone_object()); $year = $now->format('Y'); $month = $now->format('m'); $now->setDate($year, $month, 1); $dayofweek = $now->format('N'); echo $dayofweek;