在PHP中执行日期时间相关操作 [英] performing datetime related operations in PHP
问题描述
如何实际执行日期时间操作,例如添加日期,查找差异,找出间隔中不包括周末的天数?我个人开始将其中的一些操作传递给我的postgresql dbms,通常我只需要发出一个sql语句来获得答案,但是要以PHP的方式执行,我必须编写更多的代码,这意味着更多的机会发生错误...
How do you actually perform datetime operations such as adding date, finding difference, find out how many days excluding weekends in an interval? I personally started to pass some of these operations to my postgresql dbms as typically I would only need to issue one sql statement to obtain an answer, however, to do it in PHP way I would have to write a lot more code that means more chances for errors to occur...
PHP中是否存在任何不需要大量代码的日期时间操作的库?在一个两个日期中,在两个日期之间有多少个工作日的情况下,打破sql?实现在SQL或$ pet_lang',通过进行此查询解决?
Are there any libraries in PHP that does datetime operation in a way that don't require a lot of code? that beats sql in a situation where 'Given two dates, how many workdays are there between the two dates? Implement in either SQL, or $pet_lang' that is solved by making this query?
SELECT COUNT(*) AS total_days
FROM (SELECT date '2008-8-26' + generate_series(0,
(date '2008-9-1' - date '2008-8-26')) AS all_days) AS calendar
WHERE EXTRACT(isodow FROM all_days) < 6;
推荐答案
PHP5 +的DateTime对象很有用,因为它是闰秒
夏令时知道,但它需要一些扩展才能真正的
解决问题。我写了以下内容来解决类似的问题。
find_WeekdaysFromThisTo()方法是强力的,但如果你的时间不到2年,它的工作速度相当快。
PHP5+'s DateTime object is useful because it is leap time and daylight savings aware, but it needs some extension to really solve the problem. I wrote the following to solve a similar problem. The find_WeekdaysFromThisTo() method is brute-force, but it works reasonably quickly if your time span is less than 2 years.
$tryme = new Extended_DateTime('2007-8-26');
$newer = new Extended_DateTime('2008-9-1');
print 'Weekdays From '.$tryme->format('Y-m-d').' To '.$newer->format('Y-m-d').': '.$tryme -> find_WeekdaysFromThisTo($newer) ."\n";
/* Output: Weekdays From 2007-08-26 To 2008-09-01: 265 */
print 'All Days From '.$tryme->format('Y-m-d').' To '.$newer->format('Y-m-d').': '.$tryme -> find_AllDaysFromThisTo($newer) ."\n";
/* Output: All Days From 2007-08-26 To 2008-09-01: 371 */
$timefrom = $tryme->find_TimeFromThisTo($newer);
print 'Between '.$tryme->format('Y-m-d').' and '.$newer->format('Y-m-d').' there are '.
$timefrom['years'].' years, '.$timefrom['months'].' months, and '.$timefrom['days'].
' days.'."\n";
/* Output: Between 2007-08-26 and 2008-09-01 there are 1 years, 0 months, and 5 days. */
class Extended_DateTime extends DateTime {
public function find_TimeFromThisTo($newer) {
$timefrom = array('years'=>0,'months'=>0,'days'=>0);
// Clone because we're using modify(), which will destroy the object that was passed in by reference
$testnewer = clone $newer;
$timefrom['years'] = $this->find_YearsFromThisTo($testnewer);
$mod = '-'.$timefrom['years'].' years';
$testnewer -> modify($mod);
$timefrom['months'] = $this->find_MonthsFromThisTo($testnewer);
$mod = '-'.$timefrom['months'].' months';
$testnewer -> modify($mod);
$timefrom['days'] = $this->find_AllDaysFromThisTo($testnewer);
return $timefrom;
} // end function find_TimeFromThisTo
public function find_YearsFromThisTo($newer) {
/*
If the passed is:
not an object, not of class DateTime or one of its children,
or not larger (after) $this
return false
*/
if (!is_object($newer) || !($newer instanceof DateTime) || $newer->format('U') < $this->format('U'))
return FALSE;
$count = 0;
// Clone because we're using modify(), which will destroy the object that was passed in by reference
$testnewer = clone $newer;
$testnewer -> modify ('-1 year');
while ( $this->format('U') < $testnewer->format('U')) {
$count ++;
$testnewer -> modify ('-1 year');
}
return $count;
} // end function find_YearsFromThisTo
public function find_MonthsFromThisTo($newer) {
/*
If the passed is:
not an object, not of class DateTime or one of its children,
or not larger (after) $this
return false
*/
if (!is_object($newer) || !($newer instanceof DateTime) || $newer->format('U') < $this->format('U'))
return FALSE;
$count = 0;
// Clone because we're using modify(), which will destroy the object that was passed in by reference
$testnewer = clone $newer;
$testnewer -> modify ('-1 month');
while ( $this->format('U') < $testnewer->format('U')) {
$count ++;
$testnewer -> modify ('-1 month');
}
return $count;
} // end function find_MonthsFromThisTo
public function find_AllDaysFromThisTo($newer) {
/*
If the passed is:
not an object, not of class DateTime or one of its children,
or not larger (after) $this
return false
*/
if (!is_object($newer) || !($newer instanceof DateTime) || $newer->format('U') < $this->format('U'))
return FALSE;
$count = 0;
// Clone because we're using modify(), which will destroy the object that was passed in by reference
$testnewer = clone $newer;
$testnewer -> modify ('-1 day');
while ( $this->format('U') < $testnewer->format('U')) {
$count ++;
$testnewer -> modify ('-1 day');
}
return $count;
} // end function find_AllDaysFromThisTo
public function find_WeekdaysFromThisTo($newer) {
/*
If the passed is:
not an object, not of class DateTime or one of its children,
or not larger (after) $this
return false
*/
if (!is_object($newer) || !($newer instanceof DateTime) || $newer->format('U') < $this->format('U'))
return FALSE;
$count = 0;
// Clone because we're using modify(), which will destroy the object that was passed in by reference
$testnewer = clone $newer;
$testnewer -> modify ('-1 day');
while ( $this->format('U') < $testnewer->format('U')) {
// If the calculated day is not Sunday or Saturday, count this day
if ($testnewer->format('w') != '0' && $testnewer->format('w') != '6')
$count ++;
$testnewer -> modify ('-1 day');
}
return $count;
} // end function find_WeekdaysFromThisTo
public function set_Day($newday) {
if (is_int($newday) && $newday > 0 && $newday < 32 && checkdate($this->format('m'),$newday,$this->format('Y')))
$this->setDate($this->format('Y'),$this->format('m'),$newday);
} // end function set_Day
public function set_Month($newmonth) {
if (is_int($newmonth) && $newmonth > 0 && $newmonth < 13)
$this->setDate($this->format('Y'),$newmonth,$this->format('d'));
} // end function set_Month
public function set_Year($newyear) {
if (is_int($newyear) && $newyear > 0)
$this->setDate($newyear,$this->format('m'),$this->format('d'));
} // end function set_Year
} // end class Extended_DateTime
这篇关于在PHP中执行日期时间相关操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!