diff options
-rw-r--r-- | system/helpers/date_helper.php | 131 | ||||
-rw-r--r-- | user_guide_src/source/changelog.rst | 5 | ||||
-rw-r--r-- | user_guide_src/source/helpers/date_helper.rst | 26 |
3 files changed, 159 insertions, 3 deletions
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php index a792f09a2..955d74542 100644 --- a/system/helpers/date_helper.php +++ b/system/helpers/date_helper.php @@ -657,5 +657,136 @@ if ( ! function_exists('timezones')) } } +// ------------------------------------------------------------------------ + +if ( ! function_exists('date_range')) +{ + /** + * Date range + * + * Returns a list of dates within a specified period. + * + * @param int unix_start UNIX timestamp of period start date + * @param int unix_end|days UNIX timestamp of period end date + * or interval in days. + * @param mixed is_unix Specifies wether the second parameter + * is a UNIX timestamp or a day interval + * - TRUE or 'unix' for a timestamp + * - FALSE or 'days' for an interval + * @param string date_format Output date format, same as in date() + * @return array + */ + function date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d') + { + if ($unix_start == '' OR $mixed == '' OR $format == '') + { + return FALSE; + } + + $is_unix = ! ( ! $is_unix OR $is_unix === 'days'); + + // Validate input and try strtotime() on invalid timestamps/intervals, just in case + if ( ( ! preg_match('/^[0-9]+$/', $unix_start) && ($unix_start = @strtotime($unix_time)) === FALSE) + OR ( ! preg_match('/^[0-9]+$/', $mixed) && ($is_unix === FALSE OR ($mixed = @strtotime($mixed)) === FALSE)) + OR ($is_unix === TRUE && $mixed < $unix_start)) + { + return FALSE; + } + + if ($is_unix && ($unix_start == $mixed OR date($format, $unix_start) === date($format, $mixed))) + { + return array($start_date); + } + + $range = array(); + + /* NOTE: Even though the DateTime object has many useful features, it appears that + * it doesn't always handle properly timezones, when timestamps are passed + * directly to its constructor. Neither of the following gave proper results: + * + * new DateTime('<timestamp>') + * new DateTime('<timestamp>', '<timezone>') + * + * --- available in PHP 5.3: + * + * DateTime::createFromFormat('<format>', '<timestamp>') + * DateTime::createFromFormat('<format>', '<timestamp>', '<timezone') + * + * ... so we'll have to set the timestamp after the object is instantiated. + * Furthermore, in PHP 5.3 we can use DateTime::setTimestamp() to do that and + * given that we have UNIX timestamps - we should use it. + */ + $from = new DateTime(); + + if (is_php('5.3')) + { + $from->setTimestamp($unix_start); + if ($is_unix) + { + $arg = new DateTime(); + $arg->setTimestamp($mixed); + } + else + { + $arg = (int) $mixed; + } + + $period = new DatePeriod($from, new DateInterval('P1D'), $arg); + foreach ($period as $date) + { + $range[] = $date->format($format); + } + + /* If a period end date was passed to the DatePeriod constructor, it might not + * be in our results. Not sure if this is a bug or it's just possible because + * the end date might actually be less than 24 hours away from the previously + * generated DateTime object, but either way - we have to append it manually. + */ + if ( ! is_int($arg) && $range[count($range) - 1] !== $arg->format($format)) + { + $range[] = $arg->format($format); + } + + return $range; + } + + $from->setDate(date('Y', $unix_start), date('n', $unix_start), date('j', $unix_start)); + $from->setTime(date('G', $unix_start), date('i', $unix_start), date('s', $unix_start)); + if ($is_unix) + { + $arg = new DateTime(); + $arg->setDate(date('Y', $mixed), date('n', $mixed), date('j', $mixed)); + $arg->setTime(date('G', $mixed), date('i', $mixed), date('s', $mixed)); + } + else + { + $arg = (int) $mixed; + } + $range[] = $from->format($format); + + if (is_int($arg)) // Day intervals + { + do + { + $from->modify('+1 day'); + $range[] = $from->format($format); + } + while (--$arg > 0); + } + else // end date UNIX timestamp + { + for ($from->modify('+1 day'), $end_check = $arg->format('Ymd'); $from->format('Ymd') < $end_check; $from->modify('+1 day')) + { + $range[] = $from->format($format); + } + + // Our loop only appended dates prior to our end date + $range[] = $arg->format($format); + } + + return $range; + } +} + /* End of file date_helper.php */ /* Location: ./system/helpers/date_helper.php */
\ No newline at end of file diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 40ba218a8..486a67696 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -60,7 +60,8 @@ Release Date: Not Released - ``now()`` now works with all timezone strings supported by PHP. - Added an optional third parameter to ``timespan()`` that constrains the number of time units displayed. - Added an optional parameter to ``timezone_menu()`` that allows more attributes to be added to the generated select tag. - - Deprecated ``standard_date()``, which now just uses the native ``date()`` with `DateTime constants <http://bg2.php.net/manual/en/class.datetime.php#datetime.constants.types>`_. + - Deprecated ``standard_date()``, which now just uses the native ``date()`` with `DateTime constants <http://www.php.net/manual/en/class.datetime.php#datetime.constants.types>`_. + - Added function ``date_range()`` that generates a list of dates between a specified period. - ``create_captcha()`` accepts additional colors parameter, allowing for color customization. - :doc:`URL Helper <helpers/url_helper>` changes include: - ``url_title()`` will now trim extra dashes from beginning and end. @@ -75,7 +76,7 @@ Release Date: Not Released - Added a work-around in ``force_download()`` for a bug Android <= 2.1, where the filename extension needs to be in uppercase. - ``form_dropdown()`` will now also take an array for unity with other form helpers. - ``do_hash()`` now uses PHP's native ``hash()`` function (supporting more algorithms) and is deprecated. - - Removed previously deprecated helper function ``js_insert_smiley()`` from smiley helper. + - Removed previously deprecated helper function ``js_insert_smiley()`` from :doc:`Smiley Helper <helpers/smiley_helper>`. - :doc:`File Helper <helpers/file_helper>` changes include: - ``set_realpath()`` can now also handle file paths as opposed to just directories. - Added an optional paramater to ``delete_files()`` to enable it to skip deleting files such as .htaccess and index.html. diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst index e332a913f..d0c72c3c4 100644 --- a/user_guide_src/source/helpers/date_helper.rst +++ b/user_guide_src/source/helpers/date_helper.rst @@ -306,6 +306,30 @@ Example If the second parameter is empty, the current year will be used. +date_range() +============ + +Returns a list of dates within a specified period. + +.. php:method:: date_range($unix_start = '', $mixed = '', $is_unix = TRUE, $format = 'Y-m-d') + + :param integer $unix_start: UNIX timestamp of the range start date + :param integer $mixed: UNIX timestamp of the range end date or interval in days + :param boolean $is_unix: set to FALSE if $mixed is not a timestamp + :param string $format: output date format, same as in date() + :returns: array + +Example + +:: + + $range = date_range('2012-01-01', '2012-01-15'); + echo "First 15 days of 2012:"; + foreach ($range as $date) + { + echo $date."\n"; + } + timezones() =========== @@ -461,4 +485,4 @@ UP12 (UTC +12:00) Fiji, Gilbert Islands, Kamchatka, New Zealand UP1275 (UTC +12:45) Chatham Islands Standard Time UP1 (UTC +13:00) Phoenix Islands Time, Tonga UP14 (UTC +14:00) Line Islands -=========== =====================================================================
\ No newline at end of file +=========== ===================================================================== |