计算结束日期,包括周数和禁用日期

时间:2017-08-03 22:41:37

标签: javascript php date datetime jquery-ui-datepicker

我从datepicker获得了一些数据:

$disabled_dates = "08/10/2017, 08/17/2017";
$start_date = "08/03/2017";
$num_of_weeks = "20";

我正在尝试根据$start_date$num_of_weeks

计算结束日期

我知道这可以通过new Date()实现,但我不确定如何解释$disabled_dates

2 个答案:

答案 0 :(得分:3)

strtotime()对于这样的事情来说是一个非常有用的函数。 它接受各种自然语言和日期/时间输入。

从现在起20周

class Events_Calendar
{
    public IEnumerable<Event> FutureEvents => Events.Where(e => e.End >= DateTime.Today);
}

从那天开始的20周

echo date('c',strtotime('+20 weeks'))."\n";

您在 php 中的答案:

echo date('c',strtotime('08/03/2017 +20 weeks'))."\n";

修改1:将GMT添加到所有strtotime()转换中,以避免夏令时更改日期之间的秒数问题。有些日子是23小时,有些是25日,因为夏令时。 Leap seconds在unix时间不是问题。

编辑2 javascript

回答
$disabled_dates = "08/10/2017, 08/17/2017";
$start_date = "08/03/2017";
$num_of_weeks = "20";

$the_end = strtotime($start_date.' GMT +'.$num_of_weeks.' weeks');

//make all the disabled dates into timestamps for easy comparison later
$disabled_dates_array = array();
foreach(explode(',', $disabled_dates) as $date){
  $disabled_dates_array[] = strtotime(trim($date).' GMT');
}

//now compare and delay the end date if needed
foreach($disabled_dates_array as $timestamp){
  //if there was a disabled date before the end, add a day's worth of seconds
  //strtotime() returns false if it can't parse the date, so make sure it's truthy
  if($timestamp && $timestamp <= $the_end){
    $the_end += 86400;
  }
}

$enddate = date('m/d/Y',$the_end);

这里我遇到了夏令时问题

var disabled_dates = "08/10/2017, 08/17/2017";
var start_date = "08/03/2017";
var num_of_weeks = "20";

var the_end = Date.parse(start_date + ' GMT') + parseInt(num_of_weeks)*7*86400*1000;

//in javascript Date.parse is similar to php's strtotime,
//but it returns milliseconds instead of seconds
disabled_dates = disabled_dates.split(", ");
for(var i = 0, len = disabled_dates.length; i < len; i++){
  disabled_dates[i] = Date.parse(disabled_dates[i] + ' GMT');
  if(disabled_dates[i] && disabled_dates[i] <= the_end){
the_end += 86400000;
  }
}

the_end = new Date(the_end);
var enddate = ('0' + (the_end.getUTCMonth() + 1)).substr(-2) + '/' + ('0' + the_end.getUTCDate()).substr(-2) + '/' + the_end.getUTCFullYear();
console.log(enddate);

因此,在日期结束时添加“GMT”(GMT标准时间)非常重要,否则结果可能会在一天之内消失。

This video让我们深入了解如何让时间变得复杂。

答案 1 :(得分:1)

我不确定是否有更简单的方法,但那就是我会做的:

// Put dates into array or split the string
$disabled = array(new DateTime('2012-08-01'),new DateTime('2017-09-19'));

$end_date = $date->add(new DateInterval('P'.$num_of_weeks.'D'));
$range = new DatePeriod($start_date, new DateInterval('P1D'),$end_date);

// remove disabled days
foreach($range as $date){
    if(in_array($date,$disabled))
        $end_date = $end_date->sub(new DateInterval('P1D'));
}

代码未经过测试但应该可以使用。如果没有,请告诉我xD。

希望有所帮助。