簡體   English   中英

將預訂日歷的日期標記為完全可用,部分可用或不可用

[英]Marking a booking calendar's dates as completely available, partially available, or unavailable

我正在處理包含入住和退房日期的預訂日歷。 我需要能夠:

  1. 顯示任何給定月份的日歷

  2. 對於日歷上的每個日期,請指明日期是完全可用,部分可用還是不可用

對於上面列表中的第一項,我正在使用David Walsh的“使用PHP,XHTML和CSS構建日歷”一文中的代碼 萬一鏈接變壞,下面是代碼:

CSS

/* calendar */
table.calendar      { border-left:1px solid #999; }
tr.calendar-row {  }
td.calendar-day { min-height:80px; font-size:11px; position:relative; } * html div.calendar-day { height:80px; }
td.calendar-day:hover   { background:#eceff5; }
td.calendar-day-np  { background:#eee; min-height:80px; } * html div.calendar-day-np { height:80px; }
td.calendar-day-head { background:#ccc; font-weight:bold; text-align:center; width:120px; padding:5px; border-bottom:1px solid #999; border-top:1px solid #999; border-right:1px solid #999; }
div.day-number      { background:#999; padding:5px; color:#fff; font-weight:bold; float:right; margin:-5px -5px 0 0; width:20px; text-align:center; }
/* shared */
td.calendar-day, td.calendar-day-np { width:120px; padding:5px; border-bottom:1px solid #999; border-right:1px solid #999; }

的PHP

/* draws a calendar */
function draw_calendar($month,$year){

    /* draw table */
    $calendar = '<table cellpadding="0" cellspacing="0" class="calendar">';

    /* table headings */
    $headings = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
    $calendar.= '<tr class="calendar-row"><td class="calendar-day-head">'.implode('</td><td class="calendar-day-head">',$headings).'</td></tr>';

    /* days and weeks vars now ... */
    $running_day = date('w',mktime(0,0,0,$month,1,$year));
    $days_in_month = date('t',mktime(0,0,0,$month,1,$year));
    $days_in_this_week = 1;
    $day_counter = 0;
    $dates_array = array();

    /* row for week one */
    $calendar.= '<tr class="calendar-row">';

    /* print "blank" days until the first of the current week */
    for($x = 0; $x < $running_day; $x++):
        $calendar.= '<td class="calendar-day-np"> </td>';
        $days_in_this_week++;
    endfor;

    /* keep going with days.... */
    for($list_day = 1; $list_day <= $days_in_month; $list_day++):
        $calendar.= '<td class="calendar-day">';
            /* add in the day number */
            $calendar.= '<div class="day-number">'.$list_day.'</div>';

            /** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !!  IF MATCHES FOUND, PRINT THEM !! **/
            $calendar.= str_repeat('<p> </p>',2);

        $calendar.= '</td>';
        if($running_day == 6):
            $calendar.= '</tr>';
            if(($day_counter+1) != $days_in_month):
                $calendar.= '<tr class="calendar-row">';
            endif;
            $running_day = -1;
            $days_in_this_week = 0;
        endif;
        $days_in_this_week++; $running_day++; $day_counter++;
    endfor;

    /* finish the rest of the days in the week */
    if($days_in_this_week < 8):
        for($x = 1; $x <= (8 - $days_in_this_week); $x++):
            $calendar.= '<td class="calendar-day-np"> </td>';
        endfor;
    endif;

    /* final row */
    $calendar.= '</tr>';

    /* end the table */
    $calendar.= '</table>';

    /* all done, return result */
    return $calendar;
}

/* sample usages */
echo '<h2>July 2009</h2>';
echo draw_calendar(7,2009);

echo '<h2>August 2009</h2>';
echo draw_calendar(8,2009);

我被卡在該問題頂部列表中的第二個項目上。 我的目標是制作一個類似於以下內容的日歷:

日歷示例

我在David Walsh的PHP代碼中看到了以下注釋:

/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !!  IF MATCHES FOUND, PRINT THEM !! **/

可以在該注釋的位置放置一個數據庫查詢,並讓查詢查找一行,該行將導致該日期未標記為完全可用,然后,如果找到一行,則對其進行適當的標記。 我不喜歡這個想法的地方是,對於一個月的日歷,我至少要打28次數據庫。 我寧願先做一個查詢,產生這樣的數組:

$events = array(
    array(
        'check_in_date' => '2014-11-18',
        'check_out_date' => '2014-11-19',
    ),
    array(
        'check_in_date' => '2014-11-19',
        'check_out_date' => '2014-11-21',
    ),
    array(
        'check_in_date' => '2014-11-24',
        'check_out_date' => '2014-11-27',
    ),
);

這樣,我可以執行與上面相同的邏輯,但是引用數組而不是執行數據庫查詢。 不過,我不確定該怎么做。 在David Walsh的文章中看到了此評論,其中有人實現了這一目標,但他們沒有發布所使用的代碼。 我給該人發送了電子郵件,但是已經快一個星期了,我仍然沒有收到回復。

關於如何最好地完成此問題頂部列表中第二項的任何想法?

您正在尋找這樣的東西:

$year = 2014;
$month = 11;

define('FREE', 'free');
define('PARTIAL_CHECKOUT', 'unavailable in the morning');
define('PARTIAL_CHECKIN', 'unavailable from the afternoon');
define('FULL', 'unavailable');

$nb_days = date("t", strtotime("$year-$month-01"));
$begin_month_tm = strtotime("$year-$month-01");
$end_month_tm = strtotime("$year-$month-$nb_days 23:59:59");

$days = array_fill(1, $nb_days, FREE);

foreach ($events as $event)
{
    $check_in_tm = strtotime($event['check_in_date']);
    $check_out_tm = strtotime($event['check_out_date']);

    if (($check_out_tm < $begin_month_tm) || ($check_in_tm > $end_month_tm))
    {
        continue;
    }

    if ($check_in_tm >= $begin_month_tm)
    {
        $inD = (int)substr($event['check_in_date'], strrpos($event['check_in_date'], '-') + 1);
        $days[$inD] = $days[$inD] == FREE ? PARTIAL_CHECKIN : FULL;
    }
    else
    {
        $inD = 0;
    }

    if ($check_out_tm <= $end_month_tm)
    {
        $outD = (int)substr($event['check_out_date'], strrpos($event['check_out_date'], '-') + 1);
        $days[$outD] = $days[$outD] == FREE ? PARTIAL_CHECKOUT : FULL;
    }
    else
    {
        $outD = $nb_days + 1;
    }

    for ($day = $inD + 1; ($day < $outD); $day++)
    {
        $days[$day] = FULL;
    }
}

var_dump($days);

與上下文:

$events = array (
        array (
                'check_in_date' => '2014-10-29',
                'check_out_date' => '2014-11-02',
        ),
        array (
                'check_in_date' => '2014-11-18',
                'check_out_date' => '2014-11-19',
        ),
        array (
                'check_in_date' => '2014-11-19',
                'check_out_date' => '2014-11-21',
        ),
        array (
                'check_in_date' => '2014-11-24',
                'check_out_date' => '2014-11-27',
        ),
        array (
                'check_in_date' => '2014-11-29',
                'check_out_date' => '2014-12-03',
        ),
);

你會得到:

array(30) {
  [1]=>
  string(11) "unavailable"
  [2]=>
  string(26) "unavailable in the morning"
  [3]=>
  string(4) "free"
  [4]=>
  string(4) "free"
  [5]=>
  string(4) "free"
  [6]=>
  string(4) "free"
  [7]=>
  string(4) "free"
  [8]=>
  string(4) "free"
  [9]=>
  string(4) "free"
  [10]=>
  string(4) "free"
  [11]=>
  string(4) "free"
  [12]=>
  string(4) "free"
  [13]=>
  string(4) "free"
  [14]=>
  string(4) "free"
  [15]=>
  string(4) "free"
  [16]=>
  string(4) "free"
  [17]=>
  string(4) "free"
  [18]=>
  string(30) "unavailable from the afternoon"
  [19]=>
  string(11) "unavailable"
  [20]=>
  string(11) "unavailable"
  [21]=>
  string(26) "unavailable in the morning"
  [22]=>
  string(4) "free"
  [23]=>
  string(4) "free"
  [24]=>
  string(30) "unavailable from the afternoon"
  [25]=>
  string(11) "unavailable"
  [26]=>
  string(11) "unavailable"
  [27]=>
  string(26) "unavailable in the morning"
  [28]=>
  string(4) "free"
  [29]=>
  string(30) "unavailable from the afternoon"
  [30]=>
  string(11) "unavailable"
}

與上下文:

$events = array (
        array (
                'check_in_date' => '2014-10-29',
                'check_out_date' => '2014-12-03',
        ),
);

你會得到:

array(30) {
  [1]=>
  string(11) "unavailable"
  [2]=>
  string(11) "unavailable"
  [3]=>
  string(11) "unavailable"
  [4]=>
  string(11) "unavailable"
  [5]=>
  string(11) "unavailable"
  [6]=>
  string(11) "unavailable"
  [7]=>
  string(11) "unavailable"
  [8]=>
  string(11) "unavailable"
  [9]=>
  string(11) "unavailable"
  [10]=>
  string(11) "unavailable"
  [11]=>
  string(11) "unavailable"
  [12]=>
  string(11) "unavailable"
  [13]=>
  string(11) "unavailable"
  [14]=>
  string(11) "unavailable"
  [15]=>
  string(11) "unavailable"
  [16]=>
  string(11) "unavailable"
  [17]=>
  string(11) "unavailable"
  [18]=>
  string(11) "unavailable"
  [19]=>
  string(11) "unavailable"
  [20]=>
  string(11) "unavailable"
  [21]=>
  string(11) "unavailable"
  [22]=>
  string(11) "unavailable"
  [23]=>
  string(11) "unavailable"
  [24]=>
  string(11) "unavailable"
  [25]=>
  string(11) "unavailable"
  [26]=>
  string(11) "unavailable"
  [27]=>
  string(11) "unavailable"
  [28]=>
  string(11) "unavailable"
  [29]=>
  string(11) "unavailable"
  [30]=>
  string(11) "unavailable"
}

阿蘭·蒂布朗(Alain Tiemblo)的回答使我大部分都走了。 沒有他,我做不到。 雖然他的答案有些問題,但是我覺得他的答案應該是一個起點,而不是一個全面的答案,這很好。 這是最后的代碼,用於處理諸如顯示月份前一個月的入住日期,顯示月份之后一個月的退房日期之類的事情:

$year = 2014;
$month = 11;
$totalDays = date("t", strtotime("$year-$month-01"));

define('FREE', 'free');
define('PARTIAL_CHECKOUT', 'unavailable in the morning');
define('PARTIAL_CHECKIN', 'unavailable from the afternoon');
define('FULL', 'unavailable');

$days = array_fill(1, $totalDays, FREE);

foreach ($events as $event)
{
    list($inY, $inM, $inD) = explode('-', $event['check_in_date']);
    list($outY, $outM, $outD) = explode('-', $event['check_out_date']);

    if ($inY != $year || $inM != $month)
    {
        // The check-in date is in a month before the month being displayed.

        $inD = 1;

        if ($outD != 1)
        {
            $days[$inD] = FULL;
        }
    }
    else
    {
        $inD = (int) $inD;
        $days[$inD] = $days[$inD] == FREE ? PARTIAL_CHECKIN : FULL;
    }

    if ($outY != $year || $outM != $month)
    {
        // The check-out date is in a month after the month being displayed.

        $outD = $totalDays;

        if ($inD != $totalDays)
        {
            $days[$outD] = FULL;
        }
    }
    else
    {
        $outD = (int) $outD;
        $days[$outD] = $days[$outD] == FREE ? PARTIAL_CHECKOUT : FULL;
    }

    for ($day = $inD + 1; ($day < $outD); $day++)
    {
        $days[$day] = FULL;
    }
}

var_dump($days);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM