php计算两个时间段内的 工作日 工作小时
<?php class WorkTime
{
// 定义工作日 [1, 2, 3, 4, 5, 6, 0]
public $week_workingday = [1, 2, 3, 4, 5]; // 定义上下班时间
public $on_duty_time = '9:00:00';
public $off_duty_time = '18:00:00'; //每天工作时长
public $oneday_hours = null; public function __construct()
{
if (empty($this->oneday_hours)) {
$this->oneday_hours = $this->off_duty_time - $this->on_duty_time;
}
} public function get_working_hours(int $start_time, int $over_time)
{
// 如果工作日列表为空 返回0
$workingdays = $this->workingdays($start_time, $over_time); if (empty($workingdays)) {
return 0;
} // 如果开始时间不是工作日,将开始时间调整为第一个工作日的上班时间
// 如果截止时间不是工作日,将开始时间调整为最后一个工作日的下班时间
if (!in_array(date('Y/m/d', $start_time), $workingdays)) {
$start_time = strtotime($workingdays[0] . ' ' . $this->on_duty_time);
} if (!in_array(date('Y/m/d', $over_time), $workingdays)) {
$over_time = strtotime(end($workingdays) . ' ' . $this->off_duty_time);
} // 如果开始时间与截止时间是同一天,直接计算
// 反之分别计算开始时间与截止时间
if (date('Y/m/d', $start_time) == date('Y/m/d', $over_time)) {
$sec = $over_time - $start_time;
if ($sec > 3600 * $this->oneday_hours) {
$sec = 3600 * $this->oneday_hours;
}
// 昨天到了计算秒数
} else {
// 计算开始日工作时间
$start_day_sec = strtotime($workingdays[0] . ' ' . $this->off_duty_time) - $start_time;
if ($start_day_sec > 3600 * $this->oneday_hours) {
$start_day_sec = 3600 * $this->oneday_hours;
}
// 计算截止日工作时间
$over_day_sec = $over_time - strtotime(end($workingdays) . ' ' . $this->on_duty_time);
if ($over_day_sec > 3600 * $this->oneday_hours) {
$over_day_sec = 3600 * $this->oneday_hours;
} $all_day_sec = ((count($workingdays) - 2) * $this->oneday_hours) * 3600;
$sec = $start_day_sec + $over_day_sec + $all_day_sec;
} return $sec / 3600;
} # 计算工作日(包含开始与截止日期)
protected function workingdays($start_time, $over_time)
{
$start_time = strtotime('-1 day', $start_time);
$over_time = strtotime('-1 day', $over_time); $new_workingdays = $this->new_workingdays();
$new_holidays = $this->new_holidays();
$workingdays = []; while ($start_time < $over_time) {
$start_time = strtotime('+1 day', $start_time);
$is_holidays = in_array(date('w', $start_time), $this->week_workingday) && !in_array(date('Y/m/d', $start_time), $new_holidays);
$is_workingdays = in_array(date('Y/m/d', $start_time), $new_workingdays); if ($is_holidays || $is_workingdays) {
$workingdays[] = date('Y/m/d', $start_time);
}
} return $workingdays;
} # 新增工作日
protected function new_workingdays()
{
$days = [
'2020/05/09',
]; return $days;
} # 新增休息日
protected function new_holidays()
{
$days = [
'2020/05/01',
'2020/05/04',
'2020/05/05',
]; return $days;
} }
$start_time = strtotime('2020-05-06 10:00:00');
$over_time = strtotime('2020-05-11 18:00:00');
$work = new WorkTime();
$working_hours = $work->get_working_hours($start_time, $over_time);
var_dump($working_hours);
php计算两个时间段内的 工作日 工作小时的更多相关文章
- PHP计算两个时间段是否有交集(边界重叠不算)
优化前的版本: /** * PHP计算两个时间段是否有交集(边界重叠不算) * * @param string $beginTime1 开始时间1 * @param string $endTime1 ...
- 用VBA计算两个日期之间的工作日(去掉周末两天)
最近公司HR和Finance想算员工的工作天数,想让我帮忙写些VBA,自己从网上找了下代码,自己再改改,以下来自网络. 计算两个日期之间的工作日,用VBA,因量大,最好用数组做 Sub kk() Di ...
- C 语言实例 - 计算两个时间段的差值
C 语言实例 - 计算两个时间段的差值 C 语言实例 C 语言实例 计算两个时间段的差值. 实例 #include <stdio.h> struct TIME { int seconds; ...
- Oracle 查询两个时间段内的所有日期列表
1.查询某时间段内日期列表 select level,to_char(to_date('2013-12-31','yyyy-mm-dd')+level-1,'yyyy-mm-dd') as date_ ...
- sql server两个时间段内,求出周末的量
公司有个表记录了出差(加班)的初始时间和截止时间,现在要计算出加班时间,之前的设计并没有考虑到这部分,因此本人通过sql重新计算周末数 表formmain starttime endtime 使用游标 ...
- mysql 计算两个日期之间的工作日天数
创建透视表t500 建表 CREATE TABLE `t500` ( `id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE ...
- SQL计算两个时间段相隔时间
SQL语句: select cast(floor(datediff(minute,时间1,时间2) / 1440) as varchar)+'天'+ cast(floor((datediff(minu ...
- java计算两个时间相差(天、小时、分钟、秒)
public static Long dateDiff(String startTime, String endTime, String format, String str) { // 按照传入的格 ...
- 计算一段日期内的周末天数的php代码(星期六,星期日总和)
代码如下: /*| Author: Yang Yu <niceses@gmail.com>| @param char|int $start_date 一个有效的日期格式,例如:200910 ...
随机推荐
- .net remoting(一)
一.远程对象 ①RemoteHello.csproj 类库项目,程序集名称 RemoteHello ,默认命名空间 Wrox.ProCSharp.Remoting: ②派生自System.Marssh ...
- Rocket - diplomacy - enumerateBits
https://mp.weixin.qq.com/s/KsZqe9W_DM6W6JecK_irvA 介绍AddressSet.enumerateBits方法的实现,主要是x & (-x)的 ...
- Rocket - diplomacy - wirePrefix
https://mp.weixin.qq.com/s/DVcA2UixnB_6vgI3SjZGyQ 调试wirePrefix方法. 1. 实现 wirePrefix用于调整名称格式,其实现 ...
- Java中的String、StringBuffer和StringBuilder
作为作为一个已经入了门的java程序猿,肯定对Java中的String.StringBuffer和StringBuilder都略有耳闻了,尤其是String 肯定是经常用的.但肯定你有一点很好奇,为什 ...
- Java 第十一届 蓝桥杯 省模拟赛 梅花桩
小明每天都要练功,练功中的重要一项是梅花桩. 小明练功的梅花桩排列成 n 行 m 列,相邻两行的距离为 1,相邻两列的距离也为 1. 小明站在第 1 行第 1 列上,他要走到第 n 行第 m 列上.小 ...
- Java实现 蓝桥杯VIP 算法提高 快速幂
算法提高 快速幂 时间限制:1.0s 内存限制:256.0MB 问题描述 给定A, B, P,求(A^B) mod P. 输入格式 输入共一行. 第一行有三个数,N, M, P. 输出格式 输出共一行 ...
- Java实现 LeetCode 1227 飞机座位分配概率
1227. 飞机座位分配概率 有 n 位乘客即将登机,飞机正好有 n 个座位.第一位乘客的票丢了,他随便选了一个座位坐下. 剩下的乘客将会: 如果他们自己的座位还空着,就坐到自己的座位上, 当他们自己 ...
- Java实现第九届蓝桥杯分数
分数 题目描述 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来. 类似: 3/2 当然,这只是加了前2项而 ...
- 关于C#委托三种调用的分享
一.同步调用 1.同步调用会按照代码顺序来执行2.同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量IO操作),可能会让程序停顿很长时间,造成糟糕的用户体验,这时候异步调用就很有必要了. 举个栗子 ...
- Java设计模式之亨元模式
之前在项目中接触过亨元模式这一种设计模式,当时因为项目赶进度,因此只不过是大概的了解了一下,刚好今天有时间,就写一篇博客详细的学习一下亨元模式. 一.概念 运用共享技术有效的支持大量细粒度的对象.(来 ...