我想创建一个脚本来计算基于今天的日期+ X小时数的新日期是否会超过某个日期或更早。但是,我想只考虑营业时间(上午8点到下午18点)和工作日(不是周六或周日)。
Ex:今天的日期 - 2015年12月11日+ 30小时将导致我的日期只有10个小时且我不算周六或周日的日期?
我有一个脚本可以做到这一点,但是非常不可靠。有人有一个简单的解决方案吗?我在网上找不到任何东西。
function Diferenca($data1, $data2, $tipo){
if($data2==""){
$data2 = date("d/m/Y H:i");
}
if($tipo==""){
$tipo = "h";
}
for($i=1;$i<=2;$i++){
${"dia".$i} = substr(${"data".$i},0,2);
${"mes".$i} = substr(${"data".$i},3,2);
${"ano".$i} = substr(${"data".$i},6,4);
${"horas".$i} = substr(${"data".$i},11,2);
${"minutos".$i} = substr(${"data".$i},14,2);
}
$segundos = mktime($horas2,$minutos2,0,$mes2,$dia2,$ano2) - mktime($horas1,$minutos1,0,$mes1,$dia1,$ano1);
switch($tipo){
case "m": $difere = $segundos/60; break;
case "H": $difere = $segundos/3600; break;
case "h": $difere = round($segundos/3600); break;
case "D": $difere = $segundos/86400; break;
case "d": $difere = round($segundos/86400); break;
case "s": $difere = $segundos; break;
}
return $difere; }
function dec_Data($data){
$dia = substr($data, 8, 2);
$mes = substr($data, 5, 2);
$ano = substr($data, 0, 4);
$hr = substr($data, 11, 2);
$m = substr($data, 14, 2);
$data_retorno = $dia.'/'.$mes.'/'.$ano." ".$hr.":".$m;
return $data_retorno; }
if($data_cadastro_enc != '0000-00-00' and $data_cadastro_enc != '' and $sla_atend > 0 and $_POST["hora_abertura"] > 0 and $_POST["ativ_realizada"] != 'Projeto'){
$data_cadastro_atend = $data_cadastro_enc." ".$_POST["hora_abertura"];
$ano_data_cadastro_atend = substr($data_cadastro_atend, 0, 4);
$mes_data_cadastro_atend = substr($data_cadastro_atend, 5, 2);
$dia_data_cadastro_atend = substr($data_cadastro_atend, 8, 2);
$hr_data_cadastro_atend = substr($data_cadastro_atend, 11, 2);
$mn_data_cadastro_atend = substr($data_cadastro_atend, 14, 2);
$timestamp_atend = mktime($hr_data_cadastro_atend + $sla_atend, $mn_data_cadastro_atend, 0, $mes_data_cadastro_atend, $dia_data_cadastro_atend, $ano_data_cadastro_atend);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
switch ($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
$val_hora_atend = $data_cadastro_enc." 18:00";
while($nova_data_atend > $val_hora_atend){
$data_dif = dec_Data($nova_data_atend);
$data_dif_com = dec_Data($val_hora_atend);
$agora = Diferenca($data_dif_com, $data_dif, "m");
$soma = $agora + 840;
$ano_data_cadastro_atend_com = substr($val_hora_atend, 0, 4);
$mes_data_cadastro_atend_com = substr($val_hora_atend, 5, 2);
$dia_data_cadastro_atend_com = substr($val_hora_atend, 8, 2);
$hr_data_cadastro_atend_com = substr($val_hora_atend, 11, 2);
$mn_data_cadastro_atend_com = substr($val_hora_atend, 14, 2);
$timestamp_atend = mktime($hr_data_cadastro_atend_com, $mn_data_cadastro_atend_com + $soma, 0, $mes_data_cadastro_atend_com, $dia_data_cadastro_atend_com, $ano_data_cadastro_atend_com);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
switch($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
$val_hora_atend = substr($nova_data_atend, 0, 10)." 18:00";
}
$hr_nova_data = substr($nova_data_atend, 11, 2);
if($hr_nova_data == 0){
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 14, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 1) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 15, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 2) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 16, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 3) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 17, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 4) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 32, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
switch($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend + 32, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend + 32, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend + 32, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 5) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 33, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
switch($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend + 33, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend + 33, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend + 33, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 6) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 34, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
switch($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend + 34, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend + 34, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend + 34, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
} else if($hr_nova_data == 7) {
$ano_nova_data_atend = substr($nova_data_atend, 0, 4);
$mes_nova_data_atend = substr($nova_data_atend, 5, 2);
$dia_nova_data_atend = substr($nova_data_atend, 8, 2);
$hr_nova_data_atend = substr($nova_data_atend, 11, 2);
$mn_nova_data_atend = substr($nova_data_atend, 14, 2);
$timestamp_atend = mktime($hr_nova_data_atend + 35, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
$diaSemana = getDate($timestamp_atend);
$diaValor = $diaSemana[weekday];
switch($diaValor){
case "Saturday": $timestamp_atend = mktime($hr_nova_data_atend + 35, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 2, $ano_nova_data_atend);
break;
case "Sunday": $timestamp_atend = mktime($hr_nova_data_atend + 35, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend + 1, $ano_nova_data_atend);
break;
default: $timestamp_atend = mktime($hr_nova_data_atend + 35, $mn_nova_data_atend, 0, $mes_nova_data_atend, $dia_nova_data_atend, $ano_nova_data_atend);
}
$nova_data_atend = date("Y-m-d H:i", $timestamp_atend);
}
$sla_atend_data = $nova_data_atend;
}
答案 0 :(得分:1)
也许是这样的?
function foo(start_time, plus_hours) {
var time = new Date(+start_time),
day;
// rewind to the start of the hour
time.setMinutes(0, 0, 0);
// then
if (time.getHours() < 8) { // if before work day
time.setHours(8); // fast forward to start of work hours
}
if (time.getHours() >= 18) { // if after work day
time.setDate(time.getDate() + 1); // fast forward to tomorrow
time.setHours(8); // start of work hours
}
if ([0, 6].indexOf(time.getDay()) !== -1) { // if it is weekend
day = (time.getDay() && 2) || 1; // (no setDay method)
time.setDate(time.getDate() + day); // fast foward to monday
time.setHours(8); // start of work hours
}
// now convert plus_hours into day-length equivalents (i.e. add 14 hours for each 10 hours)
plus_hours = plus_hours + (plus_hours - Math.floor(plus_hours % (18 - 8))) * (24 - (18 - 8)) / (18 - 8);
// now work out how many hours we have until saturday
day = time.getDay();
day = (6 - day) * 24;
day = day - time.getHours();
// then
if (plus_hours > day) { // if we are going to cross into future weeks
// add 48 hours for each week (i.e. each 5 days)
plus_hours = plus_hours - day;
plus_hours = (plus_hours - Math.floor(plus_hours % (5 * 24))) * (2 * 24) / 5;
plus_hours = plus_hours + day + 2 * 24;
}
return new Date(+time + plus_hours * 60 * 60 * 1000);
}
跨越时区等可能会遇到一些麻烦,可能需要熨烫,但我已对其进行了评论,以便您了解这些概念。
答案 1 :(得分:0)
如果日期符合您的条件,您可以编写一个接受两个Date
(内置JavaScript类)和一些小时的函数,并返回true
。
它会涉及到Date()
类的争论,但可以做到。
var currentDate = new Date(); // new Date object with current date/time
currentDate; // "Fri Dec 11 2015 09:45:39 GMT-0800 (PST)"
currentDate.getHours(); // returns hours past midnight, in this case '9'
currentDate.getMinutes(); // returns minutes past last whole hour, in this case 45
currentDate.getDay(); // returns a number 1-7 representing Monday through Sunday
// creating a future date
var futureDate = new Date(2015, 12, 14, 9, 30); // 12/14/2015 at 9:30 AM
// the format is (year, month, date, hour, minute)
getDay()
是你的面包和黄油,因为它会告诉你你是否在周末(但不是假期,你需要外部数据)。
我要做的是从您尝试计算的小时数开始,并在currentDate
和futureDate
之间的每一天进行迭代,逐步减去小时数。如果您在到达0
之前futureDate
小时到达,那么您就知道它超出了范围。
答案 2 :(得分:0)
您可以使用此功能:
function getDateCompleted($date, $hours, $hoursPerDay) {
if ($hoursPerDay == 0) {
// Will never reach and prevent division by zero
return null;
}
$daysToComplete = ceil((float)$hours / $hoursPerDay);
$days = 0;
$time =strtotime($date);
while ($days < $daysToComplete) {
// Check for weekend
if (!(date('N', $date) >= 6)) {
$current = $time;
$days++;
}
$time = strtotime("+1 day", $time);
}
return date("Y-m-d", $current);
}
echo getDateCompleted("11/12/2015", 30, 10);
打印2015-11-16
答案 3 :(得分:0)
希望以下内容类似于您的需求(免费代码是免费代码......)。有很多关于日期的怪癖,所以下面尝试一个非常简单的算法来增加块的小时数,跳过周末,并处理任何超支。有一些业务规则:
它使用循环来添加日期和小时。它可以使用像Paul S这样的逻辑来计算出多少天并且这样做(我宁愿使用 setDate 而不是 setHours ,但我猜这&#39;只是我)但这对我的大脑来说更简单。既然算法是正确的,那么很容易简化代码(也许可以做非循环时间的事情)。
希望代码中的注释足够。开始时间,结束时间和周末天数是可配置的。
/* Add work hours to date, but only from 08:00 up to 18:00
** and skip weekends (Saturday, Sunday)
** Work in whole hours, bus
**
** @param {Date} date - Date to add hours to
** @param {number} hours - Integer number of hours to add
** @returns {Date} - new Date with work hours added.
*/
function addWorkHours(date, hours) {
// Setable parameters
var startHour = 8;
var endHour = 18;
// Weekend days to skip, one day for Sunday (0), two for Saturday (6)
var weekendDays = {'6':2, '0':1}; // Western: Saturday, Sunday
// var weekendDays = {'4':2, '5':1}; // Arabic: Thursday, Friday
// Calculated values
var date = new Date(+date); // Copy of provided date
var hrsPerDay = endHour - startHour;
var hrsToAdd, hrsLeftToday;
// Make sure hours is a number
hours = +hours;
// If before start time, set to start
if (date.getHours() < startHour) {
date.setHours(startHour,0,0,0);
// If after end time, set to start on next day
} else if (date.getHours() > endHour) {
date.setDate(date.getDate() + 1);
date.setHours(startHour,0,0,0);
}
// If on a weekend, skip to start hour on next working day
if (date.getDay() in weekendDays) {
date.setDate(date.getDate() + weekendDays[date.getDay()]);
date.setHours(startHour, 0,0,0);
}
// Add hours to date during business hours until exhaused
while (hours) {
// Get number of work hours left today
hrsLeftToday = endHour - date.getHours();
// If hrsLeftToday is 0 and there are hours to add, go to start tomorrow
if (!hrsLeftToday && hours) {
date.setDate(date.getDate() + 1);
date.setHours(startHour);
}
// Get hours to end time or remaining hours, whichever is less
hrsToAdd = hrsLeftToday > hours? hours : hrsLeftToday;
// Adjust hours
hours -= hrsToAdd;
// Add the hours, but don't go past end time
// If hours to add is equal the hours in a day, and there are
// more hours to add, just add one day
if (hrsToAdd == hrsPerDay && hours) {
date.setDate(date.getDate() + 1);
} else {
// Otherwise, set the hours
date.setHours(date.getHours() + hrsToAdd);
}
// If hours are zero, tidy any overlap past end hour if there is any
if (!hours) {
// If gone past end time in hours, run into next day
if (date.getHours() > endHour) {
// Get overrun, add a day and add back overrun
date.setDate(date.getDate() + 1);
date.setHours(startHour + date.getHours() - endHour);
}
// Do the same with minutes
if (date.getHours() == endHour && (date.getMinutes() || date.getSeconds())) {
date.setDate(date.getDate() + 1);
date.setHours(startHour);
}
}
// If now on a weekend, skip to next working day
if (date.getDay() in weekendDays) {
date.setDate(date.getDate() + weekendDays[date.getDay()]);
}
}
return date;
}
// Helper to parse ISO input date string as local
function parseDate(s) {
var b = s.split(/\D/);
return new Date(b[0],b[1]-1,b[2],b[3]||0,b[4]||0);
}
var d = parseDate(document.getElementById('startdate').value);
var h = document.getElementById('hrs').value;
document.getElementById('result').innerHTML = 'Start: ' + d + '<br>End: ' + addWorkHours(d, h);
&#13;
Date (yyyy-mm-dd [hh:mm:ss])<input type="text" id="startdate" value="2015-12-07"><br>
Hours to add (integer)<input type="text" id="hrs" value="100"><br>
<button onclick="
var d = parseDate(document.getElementById('startdate').value);
var h = document.getElementById('hrs').value;
document.getElementById('result').innerHTML = 'Start: ' + d + '<br>End: ' + addWorkHours(d, h);
">Add hours</button>
<div id="result"></div>
&#13;