Start using error free date manipulation code

5 views
Skip to first unread message

Alexander Obuhovich

unread,
Aug 7, 2012, 7:01:36 AM8/7/12
to Development In-Portal
Dates are cool, but when time comes to deal with date calculations, like adding minutes, changing timezones, etc. you can easily create an error, that will only be noticeable when summer time comes in effect :)

Right now we use AdoDb Date Time Library (http://phplens.com/phpeverywhere/adodb_date_library), that is quite old (developed in 2004 year) because in time, when we started using it (in PHP 4) php was having problems with dates after 2039 year (don't ask why we needed to create dates after Apocalypse).

At first I thought, that right now, when minimal In-Portal requirement is PHP 5.2.x we can easily replace "adodb_date" with "date" and "adodb_mktime" with "mktime" functions. After looking a bit deeper I found this nice article http://phpadvent.org/2011/dates-and-times-by-evert-pot, which explains new, added since PHP 5.2.x, class called DateTime, that is always available (no need to do custom compilation of PHP).

This class not only solves most of date problems, but also has methods (that are auto-completed in modern IDEs) that allow easy date manipulations.
Here are some comparison of new DateTime approach and how we did that in old procedural way.

Task #1: create date from a given string

Procedural:
$old_date = strtotime('25 Dec 2012 14:43:12');

OOP:
$old_date = new DateTime('25 Dec 2012 14:43:12');


Task #2: change time in given date

Procedural:
echo mktime(23, 59, 59, date('m', $old_date), date('d', $old_date), date('Y', $old_date));

OOP:
echo $old_date->setTime(23, 59, 59)->getTimestamp();


Task #3: do a relative date change

Procedural:
echo strtotime('+1 month -12 seconds', $old_date);

OOP:
echo $old_date->modify('+1 month -12 seconds')->getTimestamp();


In all examples, listed above, I used DateTime::getTimestamp method to get Unix timestamp back from DateTime class object. Usually it's not necessary unless you need to store that timestamp in database or elsewhere where you can't use DateTime object.
In all other cases you can use DateTime class object directly, e.g.

if ( $date1 > $date2 ) { ... }

Since DateTime class is not a regular class, but an build-in PHP extension written in C it can overload comparison operators and works as fast as procedural style functions. Other obvious benefit is that we can no do most of what kDateFormatter class does just with DateTime class help (e.g. parsing string date according to given date format).


Since dates are important I won't push this change into 5.2.x bugfix branch, but rather add it into 5.3.x feature branch.

While writing this post I tried to use DateTime class on a project having In-Portal 5.2.0 version and found, that there is no function to create date time class from timestamp and not mess it's timezone at same time in PHP 5.2. And I created one called kUtil::dateFromTimestamp (see attached patch). That function can safely be included into 5.2.1-B1 release since it's only added possibility for developer and not actually changing any existing code.


Here are tasks:

-- 
create_datetime_object_from_timestamp_feat.patch
Reply all
Reply to author
Forward
0 new messages