[英]Array of time periods with start and end date by range
I want to generate a table with values based on an array of time intervals that shows the start and end dates of each period. 我想生成一个基于时间间隔数组的值的表格,该表格显示每个周期的开始和结束日期。 The periods can be in fixed intervals, example (P1D, P1M, etc).
周期可以是固定的时间间隔,例如(P1D,P1M等)。
I already have a function that generates the closed (past) periods, but I can not find a way to do it with future dates. 我已经有一个生成关闭(过去)时间段的函数,但是我找不到找到将来日期的方法。
This is the function: 这是功能:
function interval($start, $interval, $break = 0)
{
$result = array();
$today = date("Y-m-d");
if ($break == 0) {
if ($today < $start) $break = 1;
}
$date = new DateTime($start);
$interval = new DateInterval($interval);
$f1 = date('Y-m-d', strtotime($start));
$x = TRUE;
if ($break == 0) {
do {
$date->add($interval);
$f2 = $date->format('Y-m-d');
$result[] = array(
'begin' => $f1,
'end' => $f2
);
$x = ($f1 <= $today && $f2 >= $today) ? TRUE : FALSE;
$f1 = date('Y-m-d', strtotime('+1 day', strtotime($f2)));
} while (!$x);
} else {
for ($n = 1; $n <= $break; $n++) {
$date->add($interval);
$f2 = $date->format('Y-m-d');
$result[] = array(
'begin' => $f1,
'end' => $f2
);
$f1 = date('Y-m-d', strtotime('+1 day', strtotime($f2)));
}
}
return $result;
}
For use simply call to function: 只需调用函数即可使用:
print_r(interval('2019-01-01', 'P1M'));
And result this: 结果如下:
(
[0] => Array
(
[begin] => 2019-01-01
[end] => 2019-02-01
)
[1] => Array
(
[begin] => 2019-02-02
[end] => 2019-03-01
)
)
I am looking to do the same but with future periods, for example, from 01-01-2019 to 01-01-2023 in 1-month intervals (P1M). 我希望做同样的事情,但要在未来一段时间内,例如以1个月的间隔(P1M)从01-01-2019到01-01-2023。
Update 更新
The answer of @dWinder is the closest thing to the solution I looking for without having to travel in time =), and it works very well with monthly and annual intervals, but with shorter periods (P15D, P1W, P1D), the script presents problems that I can not identify. @dWinder的答案是最接近我想要的解决方案的东西,而不必花费时间=),它在每月和每年的间隔下都非常有效,但周期较短(P15D,P1W,P1D),该脚本显示我无法识别的问题。
I updated the function that you published so that it ran through the array correctly and stayed like this: 我更新了您发布的函数,以便它正确地通过数组运行并保持如下状态:
function interval($start, $interval, $maxPeriods = 100, $end = NULL) {
$result = array();
//$today = date("Y-m-d"); ** Variable not used, disable it **
$date = new DateTime($start);
$interval = new DateInterval($interval);
$f1 = date('Y-m-d', strtotime($start));
do {
$date->add($interval);
$f2 = $date->format('Y-m-d');
$result[] = array( 'begin' => $f1, 'end' => $f2);
if ($end <> NULL && $end == $f2) break; // if over the end date stop the loop
$f1 = date('Y-m-d', strtotime('+1 day', strtotime($f2)));
} while (++$maxPeriods); // I changed -- to ++ to avoid stopping the loop
return $result;
}
The updated function is used in this way: 更新的功能以这种方式使用:
print_r(interval('2019-01-01', 'P1M', NULL, '2023-01-01'));
And the results: 结果:
(
[0] => Array
(
[begin] => 2019-01-01
[end] => 2019-02-01
)
[1] => Array
(
[begin] => 2019-02-02
[end] => 2019-03-01
)
[2] => Array
(
[begin] => 2019-03-02
[end] => 2019-04-01
)
[3] => Array
(
[begin] => 2019-04-02
[end] => 2019-05-01
)
[4] => Array
(
[begin] => 2019-05-02
[end] => 2019-06-01
)
[5] => Array
(
[begin] => 2019-06-02
[end] => 2019-07-01
)
[6] => Array
(
[begin] => 2019-07-02
[end] => 2019-08-01
)
[7] => Array
(
[begin] => 2019-08-02
[end] => 2019-09-01
)
[8] => Array
(
[begin] => 2019-09-02
[end] => 2019-10-01
)
[9] => Array
(
[begin] => 2019-10-02
[end] => 2019-11-01
)
[10] => Array
(
[begin] => 2019-11-02
[end] => 2019-12-01
)
[11] => Array
(
[begin] => 2019-12-02
[end] => 2020-01-01
)
)...
Better solution will be sending "end" argument and check it (in additional to the "maxPeriods" 更好的解决方案是发送“ end”参数并检查它(除了“ maxPeriods”
Consider the follow (notice the comment in the code): 考虑以下内容(注意代码中的注释):
function interval($start, $interval, $maxPeriods = 100, $end = null) {
$result = array();
$today = date("Y-m-d");
$date = new DateTime($start);
$interval = new DateInterval($interval);
$f1 = date('Y-m-d', strtotime($start));
do {
$date->add($interval);
$f2 = $date->format('Y-m-d');
$result[] = array( 'begin' => $f1, 'end' => $f2);
if ($end && $end < $f2) break; // if over the end date stop the loop
$f1 = date('Y-m-d', strtotime('+1 day', strtotime($f2)));
} while (--$maxPeriods); //till you get max elements
return $result;
}
Now call it with 现在用
print_r(interval('2019-01-01', 'P1M', 48));
//or
print_r(interval('2019-01-01', 'P1M', null, "2023-01-01"));
Notice that the first role encounter with break the loop (end date or max elements) 请注意,第一个角色遇到中断循环(结束日期或最大元素)
A time machine would help :) If the program correctly calculates past periods, then if it "thought" today was '2023-01-01' (give or take), it would correctly calculate the past periods. 时间机器会有所帮助:)如果程序正确地计算了过去的时间,那么如果今天“认为”是“ 2023-01-01”(给予或接受),它将正确地计算出过去的时间。 Can you add
$end
argument, default to today? 您可以添加
$end
参数,默认为今天吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.