/** * Rounds the date according to the specified precision * * The precision parameter must be one of the following constants: * * <code>DATE_PRECISION_YEAR</code> * <code>DATE_PRECISION_MONTH</code> * <code>DATE_PRECISION_DAY</code> * <code>DATE_PRECISION_HOUR</code> * <code>DATE_PRECISION_10MINUTES</code> * <code>DATE_PRECISION_MINUTE</code> * <code>DATE_PRECISION_10SECONDS</code> * <code>DATE_PRECISION_SECOND</code> * * The precision can also be specified as an integral offset from * one of these constants, where the offset reflects a precision * of 10 to the power of the offset greater than the constant. * For example: * * <code>DATE_PRECISION_YEAR - 1</code> rounds the date to the nearest 10 * years * <code>DATE_PRECISION_YEAR - 3</code> rounds the date to the nearest 1000 * years * <code>DATE_PRECISION_SECOND + 1</code> rounds the date to 1 decimal * point of a second * <code>DATE_PRECISION_SECOND + 1</code> rounds the date to 3 decimal * points of a second * <code>DATE_PRECISION_SECOND + 1</code> rounds the date to the nearest 10 * seconds (thus it is equivalent to * DATE_PRECISION_10SECONDS) * * N.B. This function requires a time in UTC if both the precision is at * least DATE_PRECISION_SECOND and leap seconds are being counted, otherwise * any local time is acceptable. * * @param int $pn_precision a 'DATE_PRECISION_*' constant * @param int $pn_day the day of the month * @param int $pn_month the month * @param int $pn_year the year * @param int $pn_hour the hour * @param int $pn_minute the minute * @param mixed $pn_second the second as integer or float * @param bool $pb_countleap whether to count leap seconds (defaults to * DATE_COUNT_LEAP_SECONDS) * * @return array array of year, month, day, hour, minute, second * @access public * @static * @since Method available since Release 1.5.0 */ function round($pn_precision, $pn_day, $pn_month, $pn_year, $pn_hour = 0, $pn_minute = 0, $pn_second = 0, $pb_countleap = DATE_COUNT_LEAP_SECONDS) { if ($pn_precision <= DATE_PRECISION_YEAR) { $hn_month = 0; $hn_day = 0; $hn_hour = 0; $hn_minute = 0; $hn_second = 0; if ($pn_precision < DATE_PRECISION_YEAR) { $hn_year = round($pn_year, $pn_precision - DATE_PRECISION_YEAR); } else { // Check part-year: // $hn_midyear = (Date_Calc::firstDayOfYear($pn_year + 1) - Date_Calc::firstDayOfYear($pn_year)) / 2; if (($hn_days = Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year)) <= $hn_midyear - 1) { $hn_year = $pn_year; } else { if ($hn_days >= $hn_midyear) { // Round up: // $hn_year = $pn_year + 1; } else { // Take time into account: // $hn_partday = Date_Calc::secondsPastMidnight($pn_hour, $pn_minute, $pn_second) / 86400; if ($hn_partday >= $hn_midyear - $hn_days) { // Round up: // $hn_year = $pn_year + 1; } else { $hn_year = $pn_year; } } } } } else { if ($pn_precision == DATE_PRECISION_MONTH) { $hn_year = $pn_year; $hn_day = 0; $hn_hour = 0; $hn_minute = 0; $hn_second = 0; $hn_firstofmonth = Date_Calc::firstDayOfMonth($pn_month, $pn_year); $hn_midmonth = (Date_Calc::lastDayOfMonth($pn_month, $pn_year) + 1 - $hn_firstofmonth) / 2; if (($hn_days = Date_Calc::dateToDays($pn_day, $pn_month, $pn_year) - $hn_firstofmonth) <= $hn_midmonth - 1) { $hn_month = $pn_month; } else { if ($hn_days >= $hn_midmonth) { // Round up: // list($hn_year, $hn_month) = Date_Calc::nextMonth($pn_month, $pn_year); } else { // Take time into account: // $hn_partday = Date_Calc::secondsPastMidnight($pn_hour, $pn_minute, $pn_second) / 86400; if ($hn_partday >= $hn_midmonth - $hn_days) { // Round up: // list($hn_year, $hn_month) = Date_Calc::nextMonth($pn_month, $pn_year); } else { $hn_month = $pn_month; } } } } else { if ($pn_precision == DATE_PRECISION_DAY) { $hn_year = $pn_year; $hn_month = $pn_month; $hn_hour = 0; $hn_minute = 0; $hn_second = 0; if (Date_Calc::secondsPastMidnight($pn_hour, $pn_minute, $pn_second) >= 43200) { // Round up: // list($hn_year, $hn_month, $hn_day) = explode(" ", Date_Calc::nextDay($pn_day, $pn_month, $pn_year, "%Y %m %d")); } else { $hn_day = $pn_day; } } else { if ($pn_precision == DATE_PRECISION_HOUR) { $hn_year = $pn_year; $hn_month = $pn_month; $hn_day = $pn_day; $hn_minute = 0; $hn_second = 0; if (Date_Calc::secondsPastTheHour($pn_minute, $pn_second) >= 1800) { // Round up: // list($hn_year, $hn_month, $hn_day, $hn_hour) = Date_Calc::addHours(1, $pn_day, $pn_month, $pn_year, $pn_hour); } else { $hn_hour = $pn_hour; } } else { if ($pn_precision <= DATE_PRECISION_MINUTE) { $hn_year = $pn_year; $hn_month = $pn_month; $hn_day = $pn_day; $hn_hour = $pn_hour; $hn_second = 0; if ($pn_precision < DATE_PRECISION_MINUTE) { $hn_minute = round($pn_minute, $pn_precision - DATE_PRECISION_MINUTE); } else { // Check seconds: // if ($pn_second >= 30) { // Round up: // list($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute) = Date_Calc::addMinutes(1, $pn_day, $pn_month, $pn_year, $pn_hour, $pn_minute); } else { $hn_minute = $pn_minute; } } } else { // Precision is at least (DATE_PRECISION_SECOND - 1): // $hn_year = $pn_year; $hn_month = $pn_month; $hn_day = $pn_day; $hn_hour = $pn_hour; $hn_minute = $pn_minute; $hn_second = round($pn_second, $pn_precision - DATE_PRECISION_SECOND); if (fmod($hn_second, 1) == 0.0) { $hn_second = (int) $hn_second; if ($hn_second != intval($pn_second)) { list($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute, $hn_second) = Date_Calc::addSeconds($hn_second - intval($pn_second), $pn_day, $pn_month, $pn_year, $pn_hour, $pn_minute, intval($pn_second), $pn_precision >= DATE_PRECISION_SECOND && $pb_countleap); // // (N.B. if rounded to nearest 10 seconds, // user does not expect seconds to be '60') } } } } } } } return array((int) $hn_year, (int) $hn_month, (int) $hn_day, (int) $hn_hour, (int) $hn_minute, $hn_second); }
/** * Add a time zone offset to the passed date/time * * @param int $pn_offset the offset to add in milliseconds * @param int $pn_day the day * @param int $pn_month the month * @param int $pn_year the year * @param int $pn_hour the hour * @param int $pn_minute the minute * @param int $pn_second the second * @param float $pn_partsecond the part-second * * @return array array of year, month, day, hour, minute, second, * and part-second * @access private * @static * @since Method available since Release 1.5.0 */ function _addOffset($pn_offset, $pn_day, $pn_month, $pn_year, $pn_hour, $pn_minute, $pn_second, $pn_partsecond) { if ($pn_offset == 0) { return array((int) $pn_year, (int) $pn_month, (int) $pn_day, (int) $pn_hour, (int) $pn_minute, (int) $pn_second, (double) $pn_partsecond); } if ($pn_offset % 3600000 == 0) { list($hn_year, $hn_month, $hn_day, $hn_hour) = Date_Calc::addHours($pn_offset / 3600000, $pn_day, $pn_month, $pn_year, $pn_hour); $hn_minute = (int) $pn_minute; $hn_second = (int) $pn_second; $hn_partsecond = (double) $pn_partsecond; } else { if ($pn_offset % 60000 == 0) { list($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute) = Date_Calc::addMinutes($pn_offset / 60000, $pn_day, $pn_month, $pn_year, $pn_hour, $pn_minute); $hn_second = (int) $pn_second; $hn_partsecond = (double) $pn_partsecond; } else { list($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute, $hn_secondraw) = Date_Calc::addSeconds($pn_offset / 1000, $pn_day, $pn_month, $pn_year, $pn_hour, $pn_partsecond == 0.0 ? $pn_second : $pn_second + $pn_partsecond, false); // N.B. do not count // leap seconds if (is_float($hn_secondraw)) { $hn_second = intval($hn_secondraw); $hn_partsecond = $hn_secondraw - $hn_second; } else { $hn_second = $hn_secondraw; $hn_partsecond = 0.0; } } } return array($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute, $hn_second, $hn_partsecond); }