【问题标题】:Finding differently lengthed time intervals between two dates在两个日期之间查找不同长度的时间间隔
【发布时间】:2018-02-13 07:02:17
【问题描述】:

我希望用户能够选择显示结果的日期范围和间隔,例如“显示 2017 年 1 月 1 日至 2017 年 4 月 1 日之间的结果,按天|周|月列出”

因此,如果他们选择日期,我会在 2017 年 1 月 1 日之前对结果进行分组; 2017 年 1 月 2 日; 2017 年 1 月 3 日;等等……

如果他们选择星期,那就是 2017 年 1 月 1 日; 2017 年 1 月 8 日; 2017 年 1 月 15 日;等等……

我现在使用的方法如下:

if(isset($chosenInterval) && ($chosenInterval == "week" || $chosenInterval == "day") ) {
    $timeFormat = "F j, Y"; 
} else {
    $timeFormat = "F Y";
    $chosenInterval = "month";
}

$start    = (new DateTime($start))->modify('first day of this month');
$end      = (new DateTime($stop))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 '.$chosenInterval);
$period   = new DatePeriod($start, $interval, $end);

foreach($period as $dt) {
    $dataLabels[] = $dt->format($timeFormat);
}   

问题是,如果用户选择2017年1月8日-2017年1月20日,它仍然包括一月份的所有日期。

理想情况下它会显示:

  • 日期:2017 年 1 月 8 日; 2017 年 1 月 9 日; ... 2017 年 1 月 19 日; 2017 年 1 月 20 日
  • 周:2017 年 1 月 8 日; 2017 年 1 月 15 日
  • 月份:2017 年 1 月

关于如何完成此任务的任何建议?谢谢!

【问题讨论】:

  • 您不想将$start$end 设置为所选的开始和结束日期有什么特别的原因吗?
  • @Aydin 不是真的,我对 DateTime 对象不是很熟悉,所以我从另一个类似的线程中提取了代码。我试图删除修改部分,但在某处遇到错误,所以我放弃了这个想法。这样做确实让我更接近了,尽管我在 2017 年 8 月 7 日 - 2017 年 9 月 7 日进行了一次测试,间隔一个月,我只回到了 8 月——不是 9 月。任何想法为什么?

标签: php date datetime intervals


【解决方案1】:

您需要在将DateTime 对象添加到$dataLabels 时检查日期是在开始之前还是结束之后。如果是(并且$chosenInterval 不是一个月),请不要添加它们:

<?php
$start = "2017-01-08";
$stop = "2017-01-20";
$chosenInterval = "week";
function getDates($start, $stop, $chosenInterval = "week") {
    $startDT = new DateTime($start); // make a DateTime out of the date to later compare it
    $stopDT = new DateTime($stop); // make a DateTime out of the date to later compare it
    if(isset($chosenInterval) && ($chosenInterval == "week" || $chosenInterval == "day") ) {
        $timeFormat = "F j, Y"; 
    } else {
        $timeFormat = "F Y";
        $chosenInterval = "month";
    }

    $begin    = (new DateTime($start))->modify('first day of this month');
    $end      = (new DateTime($stop))->modify('first day of next month');
    $interval = DateInterval::createFromDateString('1 '.$chosenInterval);
    $period   = new DatePeriod($begin, $interval, $end);

    foreach($period as $dt) {
        if ($chosenInterval !== "month" && ($dt < $startDT || $dt > $stopDT)) continue; // if date is before start or after end, skip
        $dataLabels[] = $dt->format($timeFormat);
    }
    return $dataLabels;
}
var_dump(getDates($start, $stop));
var_dump(getDates($start, $stop, "day"));
var_dump(getDates($start, $stop, "month"));

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2023-01-26
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 2015-08-06
    相关资源
    最近更新 更多