I was working on my Reference Statistics Tracker for work, and ran in to a snag.

I am using eZ Components' ezGraph class to create image-based graphs on the fly. It's fast, efficient, and it looks nice - it can even render in SVG (I'll be using JPG or PNG...thanks IE). For my particular needs, I wanted the exported dataset to have a specific formatting to the keys, to represent the different values in my graphs. For instance, let's say I have the following stats from 100 users in our company, and the Operating System they use. This is purely fictitious:
array('Windows' => 90, 'OSX' => 6, 'Other' => 4);
That specific array is crafted perfectly in the format that works well with eZ Components' Graphing class, for a simple bar chart, or a pie chart.

So now I just had to pull the values from the database in the format I wanted. Well my keys in this case were dates, or times (span of days, or hours in a day, or month in a year, etc...). The values were still numeric values in this case. So, we're looking at something like:
array('HH:MM:SS' => 10);
However, no matter how hard I tried, if there were no values inserted in to the database for a specific time, I could not return a value of null, or zero - even with an outer join. My next thought was to use something like array_merge() on the resulting dataset to fix it.

The PHP function of range() just didn't cut it. Although I could have converted the datetime values to timestamp values (either via SQL or PHP), and used the 3rd parameter of the function to add the specific number of seconds needed, I was weary of doing that as I remember reading about issues that could cause (adding seconds to a timestamp value calculate future time). Besides, I'd still have to use array_walk() or array_map() to format my array's keys the way I wanted; that left yet another function, and a line of code for the call to array_walk/map. (My host does not yet have PHP 5.3.x, which will allow for lambda functions in array_map.) So, I decided to create my own little function, and figured I'd post it here in case (1)someone could use it and it'd help them out, or (2)someone thinks there's a more efficient way of doing this and wants to give feedback.

This could be useful for similar graphing/charting code, I don't think it's specific to eZ Components'. Perhaps it could be useful for something else that I can't think of. Have fun with it.


Trackback specific URI for this entry
    No Trackbacks


    #1 Mike on 10/29/09 at 10:13 AM [Reply]
    Not really any input to your approach...just commiseration that dates are a pain to work with in any language/database. You'd think they could make it easier...
    #1.1 Brendon Kozlowski on 10/29/09 at 10:25 AM [Reply]
    Actually, considering how many different calendars and standards are used - not to mention timezones (ugh, timezones)...I honestly think that PHP does a pretty darn good job at making dates easy to work with. That being said, I haven't yet tried out Ruby (or RoR), or Python (or any of its frameworks) to see how they manage dates. There will always be edge cases that need to be take care of. I imagine this is possibly one of those edge cases (at least for PHP).

    I have recently tried ColdFusion. Its date formatting pales in comparison. Granted, I could break out in to Java code from within ColdFusion - but I don't consider that ColdFusion's strength at that point.

    Edited code in article to define $format a little better.
    #2 Annan on 08/02/11 at 02:51 AM [Reply]
    // Create some date intervals to use
    $ayear = new DateInterval('P1Y');
    $aday = new DateInterval('P1D');

    // Create our start and end date
    $now = new DateTime();
    $one_year_away = date_add(clone $now, $ayear);

    // Create the period that we want to iterate over
    $period = new DatePeriod($now,$aday,$end);

    foreach ( $period as $date ){
    //Do Shiz!
    #2.1 Brendon Kozlowski on 10/14/11 at 07:15 AM [Reply]
    Thanks, Annan! Since DatePeriod and the OOP Date methods in PHP were somewhat "new" when I wrote this post I didn't want to use them, I was opting for PHP4 compatibility. Although I've long since upgraded to PHP 5.x, there are still some issues to be had with using the OOP features of the Date classes.

    For instance: http://us.php.net/manual/en/class.dateperiod.php#102841

    However, I do humbly thank you for providing the code! In truth I wasn't aware of the DatePeriod object until you commented. :)

Add Comment

E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.

BBCode format allowed