计算一段日期内的周末天数的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 相关文章推荐
PHPlet在Windows下的安装
Oct 09 PHP
新手配置 PHP 调试环境(IIS+PHP+MYSQL)
Jan 10 PHP
PHP中MD5函数使用实例代码
Jun 07 PHP
php MsSql server时遇到的中文编码问题
Jun 11 PHP
php 遍历数据表数据并列表横向排列的代码
Sep 05 PHP
php实现rc4加密算法代码
Apr 25 PHP
php操作redis中的hash和zset类型数据的方法和代码例子
Jul 05 PHP
php实现paypal 授权登录
May 28 PHP
PHP实现简单的新闻发布系统实例
Jul 28 PHP
php实现微信公众平台账号自定义菜单类
Oct 11 PHP
php+redis在实际项目中HTTP 500: Internal Server Error故障排除
Feb 05 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
Apr 21 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
ThinkPHP中I(),U(),$this-&gt;post()等函数用法
2014/11/22 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
js计算页面刷新的次数
2009/07/20 Javascript
nodejs之请求路由概述
2014/07/05 NodeJs
Jquery简单实现GridView行高亮的方法
2015/06/15 Javascript
jQuery蓝色风格滑动导航栏代码分享
2015/08/19 Javascript
js格式化时间的方法
2015/12/18 Javascript
基于vue实现多引擎搜索及关键字提示
2017/03/16 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
2017/05/18 Javascript
AngularJS动态绑定ng-options的ng-model实例代码
2017/06/21 Javascript
详解angular应用容器化部署
2018/08/14 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
Javascript ParentNode和ChildNode接口原理解析
2020/03/16 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
python求列表交集的方法汇总
2014/11/10 Python
Python中的异常处理相关语句基础学习笔记
2016/07/11 Python
深入理解Python3中的http.client模块
2017/03/29 Python
Python with语句上下文管理器两种实现方法分析
2018/02/09 Python
python使用PIL实现多张图片垂直合并
2019/01/15 Python
Python实现合并两个有序链表的方法示例
2019/01/31 Python
Python学习笔记之视频人脸检测识别实例教程
2019/03/06 Python
django-rest-framework解析请求参数过程详解
2019/07/18 Python
python实现的爬取电影下载链接功能示例
2019/08/26 Python
django-crontab 定时执行任务方法的实现
2019/09/06 Python
django框架中间件原理与用法详解
2019/12/10 Python
canvas实现烟花的示例代码
2020/01/16 HTML / CSS
社区端午节活动方案
2014/01/28 职场文书
公司投资建议书
2014/05/16 职场文书
民主评议政风行风活动心得体会
2014/10/29 职场文书
企业员工辞职信范文
2015/05/12 职场文书
2015年大学团支部工作总结
2015/05/13 职场文书
法律服务所工作总结
2015/08/10 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
话题作文之财富(600字)
2019/12/03 职场文书
Redis 彻底禁用RDB持久化操作
2021/07/09 Redis
Python OpenCV之常用滤波器使用详解
2022/04/07 Python