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 ...
随机推荐
- jchdl - RTL Data Types
https://mp.weixin.qq.com/s/hWYW1Bn---WhpwVu2e98qA 一. Bit 类结构如下: 主要属性: value: bit的值,只支持0,1, ...
- Qcom平台RTC驱动分析
相关文件list: pm8998.dtsi ---RTC dts配置 qpnp-rtc.c ---qcom RTC驱动 class.c ---RTC相关class interface.c ---相关R ...
- Java实现 蓝桥杯 算法提高 因式分解
算法提高 8-1因式分解 时间限制:10.0s 内存限制:256.0MB 提交此题 问题描述 设计算法,用户输入合数,程序输出若个素数的乘积.例如,输入6,输出23.输入20,输出22*5. 样例 与 ...
- Java实现 蓝桥杯VIP 算法训练 阶乘末尾
问题描述 给定n和len,输出n!末尾len位. 输入格式 一行两个正整数n和len. 输出格式 一行一个字符串,表示答案.长度不足用前置零补全. 样例输入 6 5 样例输出 00720 数据规模和约 ...
- Java中环境变量PATH与CLASSPATH的区别
在安装JDK时需要添加环境变量,经常使用的环境变量有两个: PATH与CLASSPATH 下面总结一下环境变量的作用. PATH是系统用来指定可执行文件的完整路径.当在CMD中执行命令时,如果执行的可 ...
- Java实现 洛谷 P1090 合并果子
import java.io.BufferedInputStream; import java.util.Arrays; import java.util.Scanner; public class ...
- java实现第五届蓝桥杯供水设施
供水设施 X星球的居民点很多.Pear决定修建一个浩大的水利工程,以解决他管辖的N个居民点的供水问题.现在一共有N个水塔,同时也有N个居民点,居民点在北侧从1号到N号自西向东排成一排:水塔在南侧也从1 ...
- Linux文件搜索命令locate、which、grep详解
命令locate详解 命令locate,其基本功能是在文件资料库中可以快速的搜索系统文件,占用系统资源很少,例如:locate my.cnf 还可以使用locate -i [文件名],不区分大小写进行 ...
- PAT 人口普查
某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的,假设已知镇上没有超过 200 岁的老人,而今天是 2014 ...
- zabbix 监控进程,端口
环境介绍 操作系统:centos 7.4 zabbix版本:zabbix server 3.4.7 客户端:zabbix-agent 3.4.7 监控进程:mysqld 监控端口:3306 tcp 进 ...