php mysql比较日期并与用户输入日期匹配

php mysql compare dates and match with user input dates

本问题已经有最佳答案,请猛点这里访问。

我正在做一个房屋租赁的预订页面。

我有一个日期选择器,我的用户提交了一个Unix日期时间:到达和离开日期。
在MySQL上,我有一个不同季节的房子,有"季节开始"日期(年-月-日)、"季节结束"日期和"每天的价格"。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$seasons_select="SELECT id,season_start,season_end,daily_price FROM".T_ITEM_SEASONS." WHERE id_item=".ID_ITEM." ORDER BY season_start";
$res_seasons=mysql_query($seasons_select) or die("Error getting states");
$arrival_date = date('d-m-Y', $arrival_date);
$departure_date = date('d-m-Y', $departure_date);
 while ($seasons_row=mysql_fetch_assoc($res_seasons)){
  $start_date = date('d-m-Y', strtotime($seasons_row["season_start"]));
  $end_date = date('d-m-Y', strtotime($seasons_row["season_end"]));
  $current_date = $start_date;
  while($current_date != $end_date){
   $current_date = date("d-m-Y", strtotime("+1 day", strtotime($current_date)));
   $match_date = $arrival_date;
   while($match_date != $departure_date){
    $match_date = date("d-m-Y", strtotime("+1 day", strtotime($match_date)));
    if ($current_date==$match_date){
     echo $current_date.' This is one of the days! <br />';
    }      
   }    
  }
 }

如果用户到达/离开期间内的日期在一个或几个季节内,那么最佳匹配方式是什么?

我的代码可以工作…
我得到了我想要的答案,但在它之后是一个"致命错误:超过了30秒的最长执行时间"


0

好吧,你的看起来有点糟——)

我会说,让MySQL来做这项工作——首先只选择那些您想要的记录。

要检查单个日期是否在"季节"内,您必须检查它是否大于季节开始日期,小于季节结束日期。

要获得到达/离开期间任何一天所属的所有季节,您必须检查四种情况:

(|是季节的开始和结束,A是选择的到达日期,D是出发日期。)

1
2
3
4
5
S: -------------------|-----------------|------------------
1. ---------------A--------------------------D-------------
2. ---------------A-----------------D----------------------
3. -----------------------A---------D----------------------
4. -----------------------A------------------D-------------
  • 季节完全进入选定的时期。

  • 在赛季开始前到达,在赛季结束前离开。

  • 季节开始后到达,结束前离开。

  • 到达时间在赛季开始后,赛季结束后离开。

  • (之前和之后总是意味着包括,所以实际上是之前/之前和之后。)

    放入一个查询中,它可能看起来像这样,其中2013-05-04是到达日期,2013-07-04是离开日期:

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT id, season_start, season_end, daily_price FROM table
    WHERE id_item = 1234 AND (
       ('2013-05-04' <= season_start AND '2013-07-04' >= season_end) OR
       ('2013-05-04' <= season_start AND '2013-07-04' <= season_end) OR
       ('2013-05-04' >= season_start AND '2013-07-04' <= season_end) OR
       ('2013-05-04' >= season_start AND '2013-07-04' >= season_end)
    )
    ORDER BY season_start

    既然您说过将用户输入作为unix时间戳接收,那么您可以在将它们插入查询之前使用php的date()对它们进行格式化,也可以在这些地方使用mysql的FROM_UNIXTIME(123456789, '%Y-%M-%D')

    为了获得更好的性能,您应该在season_startseason_end列上创建一个索引(如果还没有到位的话)。

    编辑:正如在这个答案中所指出的,Salman在评论中提到的,两个条件(以及在应用布尔逻辑时的一点创造力)足以进行检查,因此where子句可以简化为

    2


    不要在一个季节的所有日子里循环查看给定日期是否在其范围内,而是尝试如下查询。

    1
    "SELECT id,season_start,season_end,daily_price FROM".T_ITEM_SEASONS." WHERE id_item=".ID_ITEM." AND season_start <= $arrival_date AND season_end >= $departure_date ORDER BY season_start";

    其中,$到达日期和$离开日期是日期选取器的值。

    这样你就不必为了找到匹配的日期而在这个季节的所有日子里循环。

    需要注意的一点-如果到达和离开日期跨越季节(一个季节到达,另一个季节离开),考虑所需的结果。如上所述的查询只返回到达和离开日期在同一季节内的行。