我有作为unix时间戳的
$now = strtotime("2013-12-10");
$start_date = strtotime("2013-01-01");
$end_date = strtotime("2013-12-31");
$start date
和$end date
跨越一段时间,而$now
时间戳位于两者的中间。
我还有一个可变的日期间隔,如下所示:
$interval = new DateInterval('P1W');
// or
$interval = new DateInterval('P3D');
给定以上内容,我如何获得now
所在间隔的开始和结束时间戳?$now
、$start_date
、$end_date
和间隔将是动态的。
示例
假设我有这些参数:
$start_date = '2013-01-01 00:00:00';
$end_date = '2013-12-31 23:59:59';
$now = '2013-12-10 15:45:34';
$interval = new DateInterval( 'P1W' );
我想知道$现在所在的区间的开始和结束日期。我希望从上面的参数中得到的输出是:
$int_start_date = '2013-12-10 00:00:00';
$int_end_date = '2013-12-16 23:59:59';
我认为这是一种比您的方法更简单、更干净的方法。
$start_date = new DateTime( '2013-01-01 00:00:00' );
$end_date = new DateTime( '2013-12-31 23:59:59' );
$end_date_ts = $end_date->getTimestamp();
$now = new DateTime( '2013-12-10 15:45:34' );
$now_ts = $now->getTimestamp();
$interval = new DateInterval( 'P1W' );
$periods = new DatePeriod( $start_date, $interval, $end_date );
/** @var 'DateTime $period */
foreach($periods as $period){
$periodEnd = clone $period;
$periodEnd->add($interval);
if($period < $now && $now < $periodEnd){
$result = iterator_to_array(new 'DatePeriod($period, $interval, $periodEnd->add($interval)));
$int_start_date = $result[0];
$int_end_date = $result[1];
break;
}
}
/** @var DateTime $int_start_date */
/** @var DateTime $int_end_date */
var_dump( $int_start_date->format( 'Y-m-d H:i:s' ) );
var_dump( $int_end_date->modify( '-1 Second' )->format( 'Y-m-d H:i:s' ) );
我自己也认为这个问题很棘手
$start_date = new DateTime( '2013-01-01 00:00:00' );
$end_date = new DateTime( '2013-12-31 23:59:59' );
$end_date_ts = $end_date->getTimestamp();
$now = new DateTime( '2013-12-10 15:45:34' );
$now_ts = $now->getTimestamp();
$interval = new DateInterval( 'P1W' );
$period = new DatePeriod( $start_date, $interval, $end_date );
$intervals = array();
foreach ( $period as $dt ) {
$intervals[] = $dt->getTimestamp();
}
$intervals[] = $end_date_ts;
$int_start_date = new DateTime();
$int_end_date = new DateTime();
for ( $i = 0; $i < count( $intervals ); $i++ ) {
if ( $now_ts >= $intervals[$i] && $now_ts <= $intervals[$i+1]) {
$int_start_date->setTimestamp($intervals[$i]);
$int_end_date->setTimestamp($intervals[$i+1]-1);
break;
}
}
var_dump( $int_start_date->format( 'Y-m-d H:i:s' ) );
var_dump( $int_end_date->format( 'Y-m-d H:i:s' ) );
如果有人有更好的方法,我很乐意接受。
您可以尝试:
$now = time();
$interval = new DateInterval('P1W');
$interval_seconds = $interval->s + ($interval->i * 60) + ($interval->h * 60 * 60) + ($interval->d * 60 * 60 * 24);
$half_interval = round($interval_seconds / 2);
// Unix timestamps
$interval_start = $now - $half_interval;
$interval_end = $now + $half_interval;
编辑:继评论之后的第二个答案
这只适用于长度为1的间隔,例如1周、1年等。
如果你的间隔>1,那么你需要以某种方式确定你在间隔中的距离。。。例如,间隔两周,你是在第一周还是第二周?
$now = time();
$interval = "week";
switch ($interval) {
case "year":
$start_int = strtotime(date("Y", $now)."-01-01 00:00:00");
$end_int = strtotime(date("Y", $now)."-12-31 23:59:59");
break;
case "month":
$start_int = strtotime(date("Y-m", $now)."-01 00:00:00");
$end_int = strtotime(date("Y-m-t", $now)." 23:59:59");
break;
case "week":
$start_week = date("Y-m-d", strtotime("previous Monday", $now));
$end_week = date("Y-m-d", strtotime("next Sunday", $now));
$start_int = strtotime($start_week." 00:00:00");
$end_int = strtotime($end_week." 23:59:59");
break;
case "day":
$start_int = strtotime(date("Y-m-d", $now)." 00:00:00");
$end_int = strtotime(date("Y-m-d", $now)." 23:59:59");
break;
case "hour":
$start_int = strtotime(date("Y-m-d H", $now).":00:00");
$end_int = strtotime(date("Y-m-d H", $now).":59:59");
break;
case "minute":
$start_int = strtotime(date("Y-m-d H:i", $now).":00");
$end_int = strtotime(date("Y-m-d H:i", $now).":59");
break;
}
echo date("Y-m-d H:i:s", $start_int), "<br>";
echo date("Y-m-d H:i:s", $end_int), "<br>";
更新3
我把你的答案的逻辑放在一个循环中:
$start_date = new DateTime( '2013-01-01 00:00:00' );
$end_date = new DateTime( '2013-12-31 23:59:59' );
$end_date_ts = $end_date->getTimestamp();
$now = new DateTime( '2013-12-10 15:45:34' );
$now_ts = $now->getTimestamp();
$interval = new DateInterval( 'P1W' );
$period = new DatePeriod( $start_date, $interval, $end_date );
$int_start_date = $start_date;
$int_end_date = $end_date;
foreach ( $period as $dt ) {
$timestamp = $dt->getTimestamp();
if ($now_ts >= $timestamp) {
$int_start_date->setTimestamp($timestamp);
}
if ($now_ts < $timestamp and $timestamp < $int_end_date->getTimestamp()) {
$int_end_date->setTimestamp($timestamp - 1);
}
}
var_dump( $int_start_date->format( 'Y-m-d H:i:s' ) );
var_dump( $int_end_date->format( 'Y-m-d H:i:s' ) );