简体   繁体   English

PHP 和 MySQL:仅比较日期字段中的月份和日期,而不考虑年份

[英]PHP and MySQL: Compare only month and day regardless of year in date field

I have a date field (myDate).我有一个日期字段(myDate)。 Lets say the field has the following date:假设该字段具有以下日期:

2015-01-01 2013-12-31 2015-01-01 2013-12-31

If the users searches the field (myDate) with the following search parameters:如果用户使用以下搜索参数搜索字段 (myDate):

From Date : 2018-12-31 To Date : 2019-01-05从日期: 2018-12-31到日期: 2019-01-05

I want the query to return the dates listed above 2015-01-01 and 2013-12-31 because they lie within the range of dates (when it comes to month and day) submitted by the user我希望查询返回上面列出的日期 2015-01-01 和 2013-12-31 因为它们在用户提交的日期范围内(当涉及到月份和日期时)

I tried the following query:我尝试了以下查询:

$listofUsers->whereRaw("DATE(CONCAT_WS('-',YEAR(NOW()),MONTH(myDate),DAY(myDate))) >= DATE(CONCAT_WS('-',YEAR(NOW()),MONTH(?),DAY(?)))",[$frm,$frm]);
$listofUSers->whereRaw("DATE(CONCAT_WS('-',YEAR(NOW()),MONTH(myDate),DAY(myDate))) <= DATE(CONCAT_WS('-',YEAR(NOW()),MONTH(?),DAY(?)))",[$to,$to]);

It works great for dates within the same year, but it fails if the submitted From Date and To Date are in two different years AND To Date month is smaller than From Date month.它适用于同一年内的日期,但如果提交的 From Date 和 To Date 位于两个不同的年份并且 To Date 月份小于 From Date 月份,则它会失败。

Any idea how to make this work regardless of year任何想法如何使这项工作无论年份如何

You can use this Query您可以使用此查询

$FromDate  = '2019-02-27';
$ToDate     = '2020-06-26';

SELECT * FROM `tblname` 
WHERE 
DATE(myDate) BETWEEN '$FromDate' AND '$ToDate' 
OR  
DATE(myDate) BETWEEN '$ToDate' AND '$FromDate';



SELECT * FROM `tblname` 
WHERE 
DATE(myDate) BETWEEN '2019-02-27' AND '2020-06-26' 
OR  
DATE(myDate) BETWEEN '2020-06-26' AND '2019-02-27';

It's not very clear from your question, but if I understand correctly you want this:你的问题不是很清楚,但如果我理解正确你想要这个:

SELECT *
FROM table
WHERE myDate LIKE concat('%', :start_day_of_year, '%')
AND   myDate LIKE concat('%', :end_day_of_year, '%')
$users->whereRaw($sql, [
    'start_day_of_year' => substr($fromDate, 5), 
    'end_day_of_year' => substr($toDate, 5), 
]);

definitions定义

  • From: user-input来自:用户输入
  • To: user-input至:用户输入
  • Target: database-field目标:数据库字段

logic逻辑

There are 4 cases you have to cover:您必须涵盖 4 种情况:

  1. From-Year > To-Year逐年>逐年

    No match, since you dont cover a single day.没有匹配,因为你没有覆盖一天。

  2. From-Year == To-Year.从年==到年。 (standard) (标准)

    Target has to be >= From AND Target has to be <= To.目标必须是>=AND目标必须是<=到。

  3. From-Year +1 < To-Year (From is more than 1 year relative to To) From-Year +1 < To-Year(From 相对于 To 超过 1 年)

    Match all, since you cover more than one year匹配所有,因为您覆盖一年以上

  4. From-Year +1 == To-Year.从年度+1 ==年度。 (From was last year relative to To) (From 是去年相对于 To)

    1. To >= From>=

      Match all since you cover at least a whole year.匹配所有内容,因为您至少覆盖了一整年。

    2. Target >= From OR Target <= To目标>=OR目标<=

      Match.匹配。

wrap all together包在一起

NOT(1) AND (2 OR 3 OR (4 AND (4.1 OR 4.2 )))

precourse前场

We transform day and month to a simple number, where comparison is easy:我们将日期和月份转换为一个简单的数字,比较容易:

DATE_FORMAT('2000-01-01','%m%d') will be 0101 => 101 DATE_FORMAT('2000-01-01','%m%d')将是0101 => 101

building-blocks建筑模块

  • From-Year DATE_FORMAT(?,'%Y')从年份DATE_FORMAT(?,'%Y')
  • To-Year DATE_FORMAT(?,'%Y')到今年DATE_FORMAT(?,'%Y')
  • From DATE_FORMAT(?,'%m%d')DATE_FORMAT(?,'%m%d')
  • To DATE_FORMAT(?,'%m%d')DATE_FORMAT(?,'%m%d')
  • Target DATE_FORMAT(myDate,'%m%d')目标DATE_FORMAT(myDate,'%m%d')

as sql作为 sql

-- 1
NOT(
    DATE_FORMAT(?,'%Y') > DATE_FORMAT(?,'%Y')
)
AND
(
    -- 2
    (
        DATE_FORMAT(?,'%Y') = DATE_FORMAT(?,'%Y')
        AND
        DATE_FORMAT(myDate,'%m%d') >= DATE_FORMAT(?,'%m%d')
        AND
        DATE_FORMAT(myDate,'%m%d') <= DATE_FORMAT(?,'%m%d')
    )
    OR
    -- 3
    (DATE_FORMAT(?,'%Y')+1) < DATE_FORMAT(?,'%Y')
    OR
    (
        -- 4
        (DATE_FORMAT(?,'%m%d')+1) = DATE_FORMAT(?,'%m%d')
        AND
        (
            -- 4.1
            DATE_FORMAT(?,'%m%d') >= DATE_FORMAT(?,'%m%d')
            OR
            -- 4.2
            (
                DATE_FORMAT(myDate,'%m%d') >= DATE_FORMAT(?,'%m%d')
                OR
                DATE_FORMAT(myDate,'%m%d') <= DATE_FORMAT(?,'%m%d')
            )
        )
    )
)

parameters参数

[$frm, $to, $frm, $to, $frm, $to, $frm, $to, $frm, $to, $to, $frm, $frm, $to]

You may be able to use named bindings.您也许可以使用命名绑定。 I dont know.我不知道。 (this will shorten the parameters significantly) (这将显着缩短参数)


Not testet - happy debugging:D不是 testet - 调试愉快:D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM