计算一段日期内的周末天数的php代码(星期六,星期日总和)


Posted in PHP onNovember 12, 2009
/* 
| Author: Yang Yu <niceses@gmail.com> 
| @param char|int $start_date 一个有效的日期格式,例如:20091016,2009-10-16 
| @param char|int $end_date 同上 
| @return 给定日期之间的周末天数 
*/ 
function get_weekend_days($start_date,$end_date){ if (strtotime($start_date) > strtotime($end_date)) list($start_date, $end_date) = array($end_date, $start_date); 
$start_reduce = $end_add = 0; 
$start_N = date('N',strtotime($start_date)); 
$start_reduce = ($start_N == 7) ? 1 : 0; 
$end_N = date('N',strtotime($end_date)); 
in_array($end_N,array(6,7)) && $end_add = ($end_N == 7) ? 2 : 1; 
$days = abs(strtotime($end_date) - strtotime($start_date))/86400 + 1; 
return floor(($days + $start_N - 1 - $end_N) / 7) * 2 - $start_reduce + $end_add; 
}

备注:

最近写给公司用的考勤系统,把其中的一个功能自动化,就是每个月的工作日(出勤天数)改为自动写入,于是写出以上函数,用来计算两个日期内的周六周日总数,稍微解释下吧,这个功能当然是用循环实现是最简单的,从开始那天for到结束那天,中间只要是周六或周日,就++,最后轻易算出总和,但还是那句话,循环的效率实在是不好,尤其当时间跨度过长时,惨不忍睹。

我这个函数的基本思路是四个字:前补后砍。没听懂吧?我也觉得有点莫名其妙。。。就是取得开始日期的星期数,如果不足一周,则补上对应的天数,比如开始日期是星期3,那么总天数就补上2天(星期1,星期2),如果开始日期是星期6,则补上5天,也就是6-1,就是函数中的$start_N - 1,如果开始日期恰好是周日,那么补上6天的同时,最后的结果需要减去一天(周六),也就是函数中的 $start_reduce ,好了,现在“前补”解释完了。下面讲下“后砍”,顾名思义,就是将后面多余的不足一周的天数,砍掉,例如,结束日期为星期3,那么就从总天数里减去3天,如果结束日期为星期6或者星期天,那么减去6或7的同时,还要在最后补上1或2。

算法没什么难点,核心思想就是将这个时间段调整为7的整数,然后乘以2,在减去或加上多算和少算的周六或周日,得到的就是星期六和星期日的总和。最后算一段时间内的天数,不建议用date(z)来算,因为通用性会不好,涉及到跨年的问题,如果跨多年,还要考虑闰年的问题,倒不如这样算来的直接。

改进记录,加入$is_workday 参数,可以选择是否返回工作日,默认是返回休息日

function get_weekend_days($start_date,$end_date,$is_workday = false){ if (strtotime($start_date) > strtotime($end_date)) list($start_date, $end_date) = array($end_date, $start_date); 
$start_reduce = $end_add = 0; 
$start_N = date('N',strtotime($start_date)); 
$start_reduce = ($start_N == 7) ? 1 : 0; 
$end_N = date('N',strtotime($end_date)); 
in_array($end_N,array(6,7)) && $end_add = ($end_N == 7) ? 2 : 1; 
$alldays = abs(strtotime($end_date) - strtotime($start_date))/86400 + 1; 
$weekend_days = floor(($alldays + $start_N - 1 - $end_N) / 7) * 2 - $start_reduce + $end_add; 
if ($is_workday){ 
$workday_days = $alldays - $weekend_days; 
return $workday_days; 
} 
return $weekend_days; 
}
PHP 相关文章推荐
PHP的FTP学习(一)[转自奥索]
Oct 09 PHP
用PHP和ACCESS写聊天室(十)
Oct 09 PHP
PHP 中文乱码解决办法总结分析
Jul 30 PHP
PHP性能优化 产生高度优化代码
Jul 22 PHP
解析php多线程下载远程多个文件
Jun 25 PHP
支持中文和其他编码的php截取字符串函数分享(截取中文字符串)
Mar 13 PHP
PHP中的traits实现代码复用使用实例
May 13 PHP
php简单图像创建入门实例
Jun 10 PHP
PHP实现自动识别原编码并对字符串进行编码转换的方法
Jul 13 PHP
YII2框架中excel表格导出的方法详解
Jul 21 PHP
PHP实现的CURL非阻塞调用类
Jul 26 PHP
Laravel Eloquent ORM 实现查询表中指定的字段
Oct 17 PHP
php 分库分表hash算法
Nov 12 #PHP
PHP 面向对象实现代码
Nov 11 #PHP
超级简单的php+mysql留言本源码
Nov 11 #PHP
PHP 远程关机实现代码
Nov 10 #PHP
php实现网站插件机制的方法
Nov 10 #PHP
php 向访客和爬虫显示不同的内容
Nov 09 #PHP
php 将excel导入mysql
Nov 09 #PHP
You might like
PHP中执行MYSQL事务解决数据写入不完整等情况
2014/01/07 PHP
php图片添加文字水印实现代码
2016/03/15 PHP
PHP利用正则表达式将相对路径转成绝对路径的方法示例
2017/02/28 PHP
纯js写的分页表格数据为json串
2014/02/18 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
JavaScript通过事件代理高亮显示表格行的方法
2015/05/27 Javascript
JS/Jquery判断对象为空的方法
2015/06/11 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
使用vue-cli创建项目的图文教程(新手入门篇)
2018/05/02 Javascript
Vue动态控制input的disabled属性的方法
2018/06/26 Javascript
jQuery无冲突模式详解
2019/01/17 jQuery
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
vue v-for出来的列表,点击某个li使得当前被点击的li字体变红操作
2020/07/17 Javascript
Python中装饰器的一个妙用
2015/02/08 Python
Python实现批量下载文件
2015/05/17 Python
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
2017/03/19 Python
Python 使用with上下文实现计时功能
2018/03/09 Python
详解python单元测试框架unittest
2018/07/02 Python
Python列表list排列组合操作示例
2018/12/18 Python
Python2.7版os.path.isdir中文路径返回false的解决方法
2019/06/21 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
Pycharm 安装 idea VIM插件的图文教程详解
2020/02/21 Python
解决Pymongo insert时会自动添加_id的问题
2020/12/05 Python
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
罗马尼亚在线杂货店:Pilulka.ro
2019/09/28 全球购物
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
AJAX检测用户名是否存在的方法
2021/03/24 Javascript
机关出纳岗位职责
2014/04/03 职场文书
爱护公共设施演讲稿
2014/09/13 职场文书
质量整改报告范文
2014/11/08 职场文书
监考失职检讨书
2015/01/26 职场文书
个人工作保证书
2015/02/28 职场文书
圣贤教育改变命运观后感
2015/06/16 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
Win11跳过联网界面创建本地管理账户的3种方法
2022/04/20 数码科技