Date and time values are nightmare in the world of binary (or decimal at best). There are different time formats (almost freeform), time zones, daylight saving offsets and who knows what else to consider.
As with any tricky task my rule of a thumb is to trust programming language and don’t trust Googled-up snippets too much. I needed range of days for one graph in Google Charts so I tried to make compact, flexible (and me-proof) function to generate range of dates.
Things to remember
It is important to establish time zone environment. In modern versions of PHP (which you should be using) is is handled by date_default_timezone_set function (or date.timezone in configuration). Functions that are sensitive to that will even try to raise fuss if it isn’t set.
You can format output however you like, but it is important to be very careful with date inputs. PHP does its best to interpret them, but for X possible ways to write down date there are twice that ways it can go wrong.
PHP manual has proper list of date formats. Pick one and stick with it. Since here I am writing for primary audience with different (and crazy, who puts month before day??) date format I stick to ISO formats in clear descending order.
And finally since programs usually deal with time as amount of seconds it seems easy to treat time spans as set of those (60*60*24). Bad idea to use bunch of seconds. That only works until you hit daylight saving shift or something as obscure. Will show how to work around that in my function.
Resulting function
function dateRange( $first, $last, $step = '+1 day', $format = 'Y/m/d' ) {
$dates = array();
$current = strtotime( $first );
$last = strtotime( $last );
while( $current <= $last ) {
$dates[] = date( $format, $current );
$current = strtotime( $step, $current );
}
return $dates;
}
Example usage
Daily defaults:
print_r( dateRange( '2010/07/26', '2010/08/05') );
Array (
[0] => 2010/07/26
[1] => 2010/07/27
[2] => 2010/07/28
[3] => 2010/07/29
[4] => 2010/07/30
[5] => 2010/07/31
[6] => 2010/08/01
[7] => 2010/08/02
[8] => 2010/08/03
[9] => 2010/08/04
[10] => 2010/08/05
)
Full week interval:
print_r( dateRange( '2010/07/26', '2010/08/05', '+1 week') );
Array (
[0] => 2010/07/26
[1] => 2010/08/02
)
How it works
Function takes:
- range as two dates (remember to pick bulletproof format);
- interval to generate dates (defaults to one day);
- format for date output (cosmetic).
Bulk of function is simple loop that creates dates by skipping in specified interval until out of range.
Trick part is how much to skip. strtotime function handles that. It takes timestamp value of current date and adds interval to it. It is smart enough to handle daylight saving time issues and is way more reliable than using bunch of seconds for interval.
Overall
Dates are tricky. Going over docs carefully and leaving as much as possible to native language functions is best approach to ensure nothing gets miscalculated.
Function could (and should) be extended a bit to handle corner cases better, but works fine for my current needs.
website laten maken #
Rarst #
topala #
Rarst #
Mats #
Pk Anane #
mahdi #
Rarst #
Daniel Gafitescu #
$start = implode('-', array_reverse( explode("/",$start_date) ) ); $stop = implode('-', array_reverse( explode("/",$end_date) ) ); $arDates = array(); $begin = new DateTime($start ); $end = new DateTime( $stop ); $end = $end->modify( '+1 day' ); $interval = new DateInterval('P1D'); $daterange = new DatePeriod($begin, $interval ,$end); foreach($daterange as $date){ $arDates[] = $date->format("Y-m-d"); } return $arDates;
Matteo #
steve #