Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.0.2

Bug #3330 Time elements from mysql are not working due to date parsing problem
Submitted: 2005-01-30 16:37 UTC
From: abarrei at gmail dot com Assigned: justinpatrin
Status: No Feedback Package: DB_DataObject_FormBuilder
PHP Version: 4.3.8 OS: Unix
Roadmaps: (Not assigned)    

 [2005-01-30 16:37 UTC] abarrei at gmail dot com
Description: ------------ Mysql select for time fields returns the time in the folowing format: HH:mm:ss Example 11:00:00. I looked through through the Formbuilder.php and I found you use the Date Package for the _date2array callback function and its conversion. This package receives and ISO 8601, and as an only time string is not compliant with that standard, the Date objects returns empty. * @version $Id: FormBuilder.php,v 1.119 2005/01/28 01:23:45 justinpatrin Exp $ I add the following line to the _date2array function below line 1864 // Convert to ISO 8601 format // Specialy time objects $date = strftime("%Y-%m-%dT%T",strtotime($date)); I think its a nice fix, becouse it wouldn't mess with the other types, but I haven't thought too much about any side effects though. I also noticed that the _array2date function you provide is not behaving normally. THus, you have these if clauses: if (isset($year) && isset($month) && isset($dateInput['d'])) { and if (isset($hour) && isset($dateInput['i']) && isset($dateInput['s'])) { so you expect the all year, months and dates exist for building the date string, and that all hours, minutes, and seconds exists for building the time string. As dateFormatElement and timeFormatElement let you lack of any of those fields, for example: $timeFormatElement = "H:i" It would be nice to have that function expect that and build the date with a default value (seconds=0) for example, becouse if not, the string is empty and a value of 0 is inserted into the database. I fix that function to, only the part of the time, that is what I am needing right now, I did the following fix in the if clause of the time part: if (isset($hour) && isset($dateInput['i'])) { if (!empty($strDate)) { $strDate .= ' '; } $strDate .= $hour.':'.$dateInput['i']; if (isset($dateInput['s'])) { $strDate .= ':'.$dateInput['s']; } if (isset($ampm)) { $strDate .= ' '.$ampm; } } of course I am still expecting and $hour and minuts from the time object. I know this can be overriden but I would be nice to have it fixed on the package. Let me know what you think and If I have the time when I finished what I need to finish right now I can give you a more complete array2date following this needs, if you think they are worth it. Reproduce code: --------------- N/A Expected result: ---------------- N/A Actual result: -------------- N/A


 [2005-01-30 16:51 UTC] abarrei at gmail dot com
A different _array2date function with the defaults values I was talking about. What do you think? function _array2date($dateInput, $timestamp = false) { if (isset($dateInput['M'])) { $month = $dateInput['M']; } elseif (isset($dateInput['m'])) { $month = $dateInput['m']; } elseif (isset($dateInput['F'])) { $month = $dateInput['F']; } if (isset($dateInput['Y'])) { $year = $dateInput['Y']; } elseif (isset($dateInput['y'])) { $year = $dateInput['y']; } if (isset($dateInput['H'])) { $hour = $dateInput['H']; } elseif (isset($dateInput['h'])) { $hour = $dateInput['h']; } if (isset($dateInput['a'])) { $ampm = $dateInput['a']; } elseif (isset($dateInput['A'])) { $ampm = isset($dateInput['A']); } $strDate = sprintf( "%04d-%02d-%02d %02d:%02d:%02d%s", isset($year) ? $year : 0 , isset($month) ? $month : 0 , isset($dateInput['d']) ? $dateInput['d'] : 0 , isset($hour) ? $hour : 0 , isset($dateInput['i']) ? $dateInput['i'] : 0 , isset($dateInput['s']) ? $dateInput['s'] : 0 , isset($ampm) ? " ".$ampm : "" ); //$this->debug('<i>_array2date():</i> to '.$strDate.' ...'); return $strDate; }
 [2005-02-02 19:30 UTC] justinpatrin
The problem with the first solution (strtotime and strftime) is that we're using the Date package precisely because we don't want to be limited to the start date of a Unix timestamp (which strtotime returns). I suppose we could check for a time-only format...something like this maybe: preg_match('/^\d+:\d+(:\d+|)(\s+[ap]m|)$/i', $date) Then, if this matches, prepend the date and then remove the d, l, D, m, M, F, Y, and y entries in the array. I also understand your second request and will make the seconds optional. However, I don't think it's appropriate to output a full date when only a time is asked for. If the DB (and the other code) is expecting a time-only value and the _array2date function returns a full date I could see some things not working. Then again, if you were using a full date field for storage but only wanted to deal with the time entries, this would be useful. Then again, in that situation I would recommend using a text field anyway. I *can* see a use for a day only or month only or day/month only date field.... The best way I can think of to "fix" this is to leave it basically as-is, except that if day, month, OR year is filled out, it will create a full date with defaults for un-filled-out date fields. Same for time. So it will still output only a date or only a time if only those are specified, but if just day is specified it will output 0000-00-day. For times, it will output an hour and minute of any of the (hour, min, sec) is set and if the second is set it will append that as well (and also ampm). Only hour specified: H:00 Only Minute specified: 00:i Only seconds specified: 00:00:s And so on. I've checked in these changes. You can see the diff here: This has *not been tested*. I tested to make sure that a Y-m-d date I'm using still works, but that's it. I'm not sure that a D only date (for instance) will actually get entered into the DB correctly. It may be more beneficial to have the defaults for unset values be the current day. Please test this and let me know if it works for you. I have very little testing time (as you can tell by the length of time it took me to get to this bug).