141 lines
4.3 KiB
PHP
141 lines
4.3 KiB
PHP
<?php
|
||
namespace app\common\service;
|
||
|
||
use think\facade\Log;
|
||
|
||
class WorkTimeService
|
||
{
|
||
/**
|
||
* 判断当前时间是否为工作时间
|
||
* @param string $workDay 工作日字符串,如 "1,2,3,4,5,6,7"
|
||
* @param string $workStart 上班时间,如 "8:00"
|
||
* @param string $workEnd 下班时间,如 "22:00"
|
||
* @param string|null $checkTime 要检查的时间(可选),默认当前时间
|
||
* @return bool
|
||
*/
|
||
public static function isWorkingTime(string $workDay, string $workStart, string $workEnd, string $checkTime = null): bool
|
||
{
|
||
try {
|
||
// 解析工作日配置
|
||
$workDays = self::parseWorkDays($workDay);
|
||
|
||
// 获取当前时间或指定时间
|
||
$now = $checkTime ? strtotime($checkTime) : time();
|
||
$currentWeekDay = date('N', $now); // 1-7,对应周一到周日
|
||
|
||
// 判断是否为工作日
|
||
if (!in_array($currentWeekDay, $workDays)) {
|
||
return false;
|
||
}
|
||
|
||
// 获取当天的上班和下班时间戳
|
||
$today = date('Y-m-d', $now);
|
||
$startTime = strtotime($today . ' ' . $workStart);
|
||
$endTime = strtotime($today . ' ' . $workEnd);
|
||
|
||
// 处理跨天的情况(如22:00到次日8:00)
|
||
if ($endTime < $startTime) {
|
||
// 如果当前时间在上班时间之后,则endTime为次日
|
||
if ($now >= $startTime) {
|
||
$endTime = strtotime($today . ' ' . $workEnd . ' +1 day');
|
||
} else {
|
||
// 如果当前时间在上班时间之前,则startTime为昨日
|
||
$startTime = strtotime($today . ' ' . $workStart . ' -1 day');
|
||
}
|
||
}
|
||
|
||
// 判断当前时间是否在工作时间内
|
||
return $now >= $startTime && $now <= $endTime;
|
||
|
||
} catch (\Exception $e) {
|
||
Log::error('判断工作时间出错: ' . $e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 解析工作日字符串为数组
|
||
* @param string $workDay
|
||
* @return array
|
||
*/
|
||
private static function parseWorkDays(string $workDay): array
|
||
{
|
||
if (empty($workDay)) {
|
||
return [];
|
||
}
|
||
|
||
$days = explode(',', $workDay);
|
||
$result = [];
|
||
|
||
foreach ($days as $day) {
|
||
$day = trim($day);
|
||
if (is_numeric($day) && $day >= 1 && $day <= 7) {
|
||
$result[] = (int)$day;
|
||
}
|
||
}
|
||
|
||
return array_unique($result);
|
||
}
|
||
|
||
/**
|
||
* 获取剩余工作时间(秒)
|
||
* @param string $workDay
|
||
* @param string $workStart
|
||
* @param string $workEnd
|
||
* @return int
|
||
*/
|
||
public static function getRemainingWorkTime(string $workDay, string $workStart, string $workEnd): int
|
||
{
|
||
if (!self::isWorkingTime($workDay, $workStart, $workEnd)) {
|
||
return 0;
|
||
}
|
||
|
||
$now = time();
|
||
$today = date('Y-m-d');
|
||
$endTime = strtotime($today . ' ' . $workEnd);
|
||
|
||
// 处理跨天情况
|
||
if ($endTime < $now) {
|
||
$endTime = strtotime($today . ' ' . $workEnd . ' +1 day');
|
||
}
|
||
|
||
return max(0, $endTime - $now);
|
||
}
|
||
|
||
/**
|
||
* 获取下个工作时间开始的时间戳
|
||
* @param string $workDay
|
||
* @param string $workStart
|
||
* @param string $workEnd
|
||
* @return int
|
||
*/
|
||
public static function getNextWorkTime(string $workDay, string $workStart, string $workEnd): int
|
||
{
|
||
$now = time();
|
||
$workDays = self::parseWorkDays($workDay);
|
||
$currentWeekDay = date('N', $now);
|
||
|
||
// 查找下一个工作日
|
||
$nextWorkDay = null;
|
||
for ($i = 0; $i < 7; $i++) {
|
||
$checkDay = ($currentWeekDay + $i) % 7;
|
||
$checkDay = $checkDay == 0 ? 7 : $checkDay;
|
||
|
||
if (in_array($checkDay, $workDays)) {
|
||
$nextWorkDay = $checkDay;
|
||
$daysToAdd = $i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ($nextWorkDay === null) {
|
||
return 0;
|
||
}
|
||
|
||
// 计算下一个工作日的开始时间
|
||
$nextDate = date('Y-m-d', strtotime("+{$daysToAdd} days"));
|
||
$nextStartTime = strtotime($nextDate . ' ' . $workStart);
|
||
|
||
return $nextStartTime;
|
||
}
|
||
} |