确定日期是否在两个日期之间,忽略年份

7
我需要确定一个日期(月和日)是否在另外两个日期之间。如图所示,红色突出显示了当前日期,它位于最近的日期(3月15日和11月22日)之间。但是,当我使用Unix时间戳并人为地将一年添加到日期时,脚本认为11月22日尚未发生,因此建议2月1日在3月15日和11月22日之前,而不是在它们之间。因此,我需要比较日期而不使用年份。希望这讲得清楚。我只想比较日期使用月和日,但忽略年份,并使用像图中所示的轮子框架。

你是否已经确定了范围的开始和结束日期,还是需要自动计算? - Barmar
1
你可以将日期格式化为仅包含月和日,并将其转换为天数。或者你可以简单地检查两个条件,先检查月份,然后是天数? - Roy M J
4个回答

5
你示例中的问题在于(在同一年内)上限日期比下限日期还早。在这种情况下,任何早于上限(Jan 1 - Mar 14)或晚于下限(Nov 23 - Dec 31)的日期都会介于两者之间。
<?php
    $upperBound = new DateTime("Mar 15");
    $lowerBound = new DateTime("Nov 22");
    $checkDate = new DateTime("Feb 1");

    if ($lowerBound < $upperBound) {
        $between = $lowerBound < $checkDate && $checkDate < $upperBound;
    } else {
        $between = $checkDate < $upperBound || $checkDate > $lowerBound;
    }
    var_dump($between);
?>

显示: 布尔值为真

编辑

如果您想要检查的日期是“2月29日”,且当前年份不是闰年,则DateTime将其解释为“3月1日”。

要检查一个日期是否在两个日期之间(包括这两个日期),请使用:

if ($lowerBound < $upperBound) {
    $between = $lowerBound <= $checkDate && $checkDate <= $upperBound;
} else {
    $between = $checkDate <= $upperBound || $checkDate >= $lowerBound;
}

这非常准确...感谢您提供简单而强大的代码! - user1610717
如果所涉及的日期为2月29日,并且当前年份不是闰年,则此操作将失败。 - Matthew Watson
1
@MatthewWatson:感谢您指出这一点。如果当前年份不是闰年,则DateTime将2月29日解释为3月1日。 - Herbert

0
为了解决这个问题,您可以将日期转换为形式为MMDD的4位数字。
$start = '1122';
$end = '0315';
$date = '0201';

如果您还没有按此格式格式化日期,您可以使用date('md', $timestamp),或者通过$month * 100 + $day进行计算;然后,您的测试逻辑将根据是否跨越年度边界而改变。将所有这些放在一起,它可能看起来像这样:
function isDateBetween($testM, $testD, $startM, $startD, $endM, $endD) {
    $start = $startM*100 + $startD;
    $end = $endM*100 + $endD;
    $date = $testM*100 + $testD;

    if ($start > $end) {
        // crossing a year boundary
        return ($date > $start) || ($date < $end);
    } else {
        // not crossing a year
        return ($date > $start) && ($date < $end);
    }
}

以下是调用此函数的一些示例:
// your example given above
isDateBetween(2, 1, 11, 22, 3, 15); // true

// ends the day after instead
isDateBetween(3, 16, 11, 22, 3, 15); // false

// reverse the dates in your example
isDateBetween(2, 1, 3, 15, 11, 22); // false

// ends the day after, with reversed dates
isDateBetween(3, 16, 3, 15, 11, 22); // true 

-1
//must be 2 digit month, then 2 digit day, like mm-dd
$low  = '03-15';
$high = '11-22';
$date = '02-01';

$isBetween = $date >= $low && $date <= $high;
var_dump($isBetween);

我正在使用词典排序,这是php比较字符串的方式。关键点是将最大的单位(月份)放在左侧,并确保使用零填充每个数字段到相同的长度。

如果您还没有将日期格式化为此类字符串,可以使用date('m-d', $timestamp)函数来实现。


2
你甚至可以去掉“-”,它就变成了一个四位数,可以像任何其他四位数一样安全地进行比较。 - jcsanyi
@jcsanyi非常正确,只要它保持为字符串。 - goat
它不应该保持为字符串。如果将它们转换为INT,它仍然可以正常比较。 - jcsanyi
但是02-01不大于等于03-15,201也不大于等于315。 - Herbert
@Herbert 您说得对 - 我错过了您原始问题中关于跨越一年边界的部分。请查看我的答案以获取一个可行的解决方案。 - jcsanyi

-1

试试这样。

<?php
$check_date= strtotime("31-Aug-1990");
$start_date= strtotime("10-Aug-2013");
$end_date= strtotime("30-Aug-1990");

if (date("M-d", $check_date)>date("M-d", $start_date) && date("M-d", $check_date)<date("M-d", $end_date))
    echo "in the range";
else
    echo "not in the range";

工作的代码在这里:这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接