This page is written for developers, basic knowledge of tikiwiki guts should be necessary to understand what it's about.
In 1.10 we are going to handle timezones very seriously. For now, we use either UTC either server time depending the feature, and what we want is to store real unix timestamps in the database, which means they need to be UTC.
The timezones consistency in Tiki is like yet another monstrous multi-legged beast, several coders went to fight it and we can see dead corpses here and there around timezone cave. The last champion to engage the fight is mose and he think he defeated the beast, after a brave attempt of Nyloth to unify timezones to gmt/utc.
Then now all date functions from PHP are to be avoided. Instead, we have 2 methods from Tikilib:
- ))TikiLib::date_format($format,$timestamp=false,$user=false)(( replaces date() and strftime(). It accepts timestamps retrieved from the database which are necessarly UTC, and produces formatted date using strftime syntax (with the percents, see http://php.net/strftime ). OPtional parameters are $timestamp (using time() as default if not set), and $user, if you need to retrieve a date in the way the user should like to see it (useful in mail sending, mainly).
- ))TikiLib::make_time($hour,$minute,$second,$month,$day,$year)(( replaces mktime(). It takes local time elements (hour, minute, second, month, day, year) and transforms it in an UTC timestamp.
In more :
- in user preferences, one can now choose his own timezone for display. That timezone will be taken in account by the 2 function stated above, in all the dates displayed by tiki or saved to database.
- the server timezone is now only used as default timezone for users display, if it's not set. Server timezone is setup by admin in admin general panel, and default value is provided by strftime('T').
- all dates are unix timestamp until they are displayed. We use smarty modifier tiki_long_date, tiki_short_date, tiki_long_time, tiki_short_time, tiki_long_datetime and tiki_short_datetime, which are formatted depending setup by admin in general admin panel.
- when smarty html_select_date and html_select_time are used, they fit along displayed timezone quite well. Remember to transform the output of those select fields with make_time() before insert in the database.
- the only date() and strftime() that are acceptable are those used to produce date and timestamps in logs or debug, where display on a web page by users is not involved.
- note that Tikilib has a property that holds current time. Please use $this->now in inherited classes rather than calling a new date('U') or time() when possible. But it's quite not sure it's good to use global $tikilib in other functions or methods if it's only for that. Benchmarking on a loop of 100,000 var attribution demonstrate a time of 0.77 seconds for date('U') and 0.07 for $tikilib->now.
- Pear::Date class is used for handling timezone and date manipulation, it was upgraded in 1.10, and modified to create date in gmt rather than in server date. patch is simple and should be re-applied if Pear::Date is upgraded:
Index: lib/pear/Date.php =================================================================== RCS file: /cvsroot/tikiwiki/tiki/lib/pear/Date.php,v retrieving revision 1.5 diff -r1.5 Date.php 203c203 < $this->setDate(date("Y-m-d H:i:s")); --- > $this->setDate(gmdate("Y-m-d H:i:s")); 253c253 < $this->setDate(date("Y-m-d H:i:s", $date)); --- > $this->setDate(gmdate("Y-m-d H:i:s", $date));
- the format syntax usable with ))TikiLib::date_format(( is almost the same than the one of strftime, but not exactly the same. Here is the list of possible formatting options:
%a abbreviated weekday name (Sun, Mon, Tue) %A full weekday name (Sunday, Monday, Tuesday) %b abbreviated month name (Jan, Feb, Mar) %B full month name (January, February, March) %C century number (the year divided by 100 and truncated to an integer, range 00 to 99) %d day of month (range 00 to 31) %D same as "%m/%d/%y" %e day of month, single digit (range 0 to 31) %E number of days since unspecified epoch (integer, Date_Calc::dateToDays()) %H hour as decimal number (00 to 23) %I hour as decimal number on 12-hour clock (01 to 12) %j day of year (range 001 to 366) %m month as decimal number (range 01 to 12) %M minute as a decimal number (00 to 59) %n newline character (\n) %O dst-corrected timezone offset expressed as "+/-HH:MM" %o raw timezone offset expressed as "+/-HH:MM" %p either 'am' or 'pm' depending on the time %P either 'AM' or 'PM' depending on the time %r time in am/pm notation, same as "%I:%M:%S %p" %R time in 24-hour notation, same as "%H:%M" %s seconds including the decimal representation smaller than one second %S seconds as a decimal number (00 to 59) %t tab character (\t) %T current time, same as "%H:%M:%S" %w weekday as decimal (0 = Sunday) %U week number of current year, first sunday as first week %y year as decimal (range 00 to 99) %Y year as decimal including century (range 0000 to 9999) %% literal '%'
If you are a tikiwiki contributor and wish to help, here is what are next tasks to overcome on the timezone track:
- spread the use of date_format and make_time all over tikiwiki, replacing the several previous attempts to address that issue (most of them where working quite well in a this or that feature, and they can be easily replaced by those only 2 functions)
- fix the calendar to make it display and save proper dates
- rewrite those damn strange modules templates/modules mod-calendar.tpl and templates/modules/mod-events.tpl they include php in smarty and that is baaaad. They also use a duplicate class for calendar, that is only used by those modules (lib/class_calendar.php). Removing that class is welcome.
- remove call to Tikidate class, which extends Date from Pear, as it should not be useful anymore when the tikilib functions will have been spreaded (to be confirmed, please provide feedback on this if you have).
- spread the use opf $this->now in classes extending tikilib.
- handle the migration of old database timestamps that are not UTC.
Please give your feedback and comments here.