计算一段日期内的周末天数的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脚本加密专家php解密算法
Sep 13 PHP
php中使用Curl、socket、file_get_contents三种方法POST提交数据
Aug 12 PHP
用PHP实现小写金额转换大写金额的代码(精确到分)
Jan 10 PHP
使用php get_headers 判断URL是否有效的解决办法
Apr 27 PHP
分享一个超好用的php header下载函数
Jan 31 PHP
php阻止页面后退的方法分享
Feb 17 PHP
ThinkPHP的常用配置选项汇总
Mar 24 PHP
PHPExcel简单读取excel文件示例
May 26 PHP
Yii2.0实现的批量更新及批量插入功能示例
Jan 29 PHP
ThinkPHP3.2框架操作Redis的方法分析
May 05 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
Mar 18 PHP
PHP 扩展Memcached命令用法实例总结
Jun 04 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 excel reader读取excel内容存入数据库实现代码
2012/12/06 PHP
在laravel中实现ORM模型使用第二个数据库设置
2019/10/24 PHP
jQuery Flash/MP3/Video多媒体插件
2010/01/18 Javascript
jquery URL参数判断,确定菜单样式
2010/05/31 Javascript
jQuery 联动日历实现代码
2012/05/31 Javascript
onbeforeunload与onunload事件异同点总结
2013/06/24 Javascript
JavaScript包装对象使用介绍
2013/08/29 Javascript
JS中怎样判断undefined(比较不错的方法)
2014/03/27 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
2015/07/27 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
2015/10/30 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
jQuery Ajax 全局调用封装实例代码详解
2016/06/02 Javascript
让html元素随浏览器的大小自适应垂直居中的实现方法
2016/10/12 Javascript
VUE axios上传图片到七牛的实例代码
2017/07/28 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
2018/05/29 Javascript
js实现简单掷骰子效果
2019/10/24 Javascript
[40:10]2015国际邀请赛全明星表演赛
2015/08/07 DOTA
[02:16]2018年度CS GO最具人气选手-完美盛典
2018/12/16 DOTA
[07:37]DOTA2-DPC中国联赛2月2日Recap集锦
2021/03/11 DOTA
Python手机号码归属地查询代码
2016/05/04 Python
python实现简易内存监控
2018/06/21 Python
python3 下载网络图片代码实例
2019/08/27 Python
基于Python新建用户并产生随机密码过程解析
2019/10/08 Python
Python文件操作基础流程解析
2020/03/19 Python
波兰在线儿童和婴儿用品零售商:pinkorblue
2019/06/29 全球购物
Unix里面如何在后台运行程序
2016/10/14 面试题
2014学年自我鉴定
2014/02/23 职场文书
考核评语大全
2014/04/29 职场文书
幼儿园校园小喇叭广播稿
2014/10/17 职场文书
党员证明模板
2015/06/19 职场文书
初中班主任工作随笔
2015/08/15 职场文书
【DOTA2】当街暴打?PSG LGD vs VG - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA
DIY胆机必读:各国电子管评价
2022/04/06 无线电
Python中的 enumerate和zip详情
2022/05/30 Python