我希望在PHP中将两个时间戳之间的范围划分为几周。
基本上,我想做的是:
function divide_into_weeks($start_time, $end_time) {
// Iterate back from the end time,
// creating an array of timestamps broken into calendar weeks.
$done = FALSE;
$divider = $end_time;
for ($i = 0; !$done; $i++) {
$timeslots[$i]->end = $divider;
// Set the start time to the start of the current week.
$timeslots[$i]->start = strtotime("monday this week", $divider);
if ($timeslots[$i]->start <= $start_time) {$done = TRUE;}
// If we loop again, end the previous week one second before the start of this week.
$divider = $timeslots[$i]->start - 1;
}
}
然而,该函数遇到无限循环。
为什么呢?因为...
strtotime("monday this week", $monday_of_next_week -1) == $monday_of_last week;
......是的,奇怪的是。这与我测试的其他strtotime操作不同。在其他情况下,你敲了一下,重复一遍,然后用你要求的任何单位之一迭代。但不是本周一(或周日)。
例如:
$today = strtotime("midnight");
$yesterday = strtotime("midnight", $today -1);
...产生明智的结果。
但是到目前为止,我尝试使用“本周一周日”或“本周日”的相同技术已证明毫无结果。
那么,有人可以展示如何将时间戳重复几周吗?
答案 0 :(得分:1)
我认为这会对你有所帮助:
function divide_into_weeks($start_time, $end_time, $tz) {
$tz = new DateTimezone($tz);
$start = new DateTime("@$start_time");
$end = new DateTime("@$end_time");
$start ->setTimezone($tz)->modify($start->format('o-\WW-1 00:00:00'));
$end ->setTimezone($tz)->modify($end ->format('o-\WW-7'));
$weeks = [];
do {
$weeks[] = [
'start' => clone $start,
'end' => new DateTime($start->format('o-\WW-7 23:59:59'), $tz),
];
$start->modify('+7 day');
} while ($start < $end);
return $weeks;
}
答案 1 :(得分:0)
这最终成为了解决方法: (修剪了一些不相关的位。)
function divide_timespan_into_units($start_second, $end_second, $time_unit) {
$timeslots = array();
// The time_formatter guides strtotime in what parts of a timestamp to trim off to leave timestamps split on calendar divisions.
switch ($time_unit) {
case "hour":
$time_formatter = 'Y-m-d H:00:00';
break;
case "day":
$time_formatter = 'Y-m-d 00:00:00';
break;
case "week":
$time_formatter = "monday this week";
break;
}
$done = FALSE;
$divider = $end_second;
for ($i = 0; !$done; $i++) {
$timeslots[$i] = (object) array('end' => $divider);
if ($time_unit == "week") {
// Dividing timestamps up into calendar weeks requires special handling.
//
// Note on the strange constants "86399" & "86400" in the two lines following:
// This is a workaround for a fluke in how strtotime treats weeks:
//
// strtotime can't decide if Sunday or Monday is the start of the week.
// You have to force it by rolling back a full day plus one second from the start of Monday, to get into the previous week.
//
// Simply rolling back a second from Sunday by 1 second doesn't get you into the previous week,
// because if you ask for "this Sunday" on any day other than Sunday, it will return the coming Sunday, not the past Sunday.
// However, if you back up 1 second from the stroke of midnight Monday, and ask what week you're in,
// you'll be told that you're still in the same week.
//
// This nudge of an extra 86400 seconds (a full extra day) back and forth forces the week to click over.
//
// This will likely be settled in a later version of PHP, but as of 5.3.5 (when this is being coded) it's an issue.
$timeslots[$i]->start = strtotime("monday this week", $divider-86400);
$divider = $timeslots[$i]->start+86399;
} else {
$timeslots[$i]->start = strtotime(date($time_formatter, $divider));
}
if ($timeslots[$i]->start <= $start_second) {$done = TRUE;}
$divider = $timeslots[$i]->start - 1;
}
}