homepage Welcome to WebmasterWorld Guest from 54.197.183.230
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Days between Dates
calculate days in each month between two dates
Tourex

10+ Year Member



 
Msg#: 4343017 posted 9:23 am on Jul 23, 2011 (gmt 0)

I need to calculate monthly occupancy levels in a simple reservation system. The MySQL database stores an arrival and a departure date in YYYY-MM-DD format. Iím tearing my hair out trying to find a simple way for PHP to work out the days for each month when the reservation crosses one or more month ends.

Take an arrival of 2011-03-25 and departure of 2011-05-03 for example. How can I calculate the results (March = 7 day; April = 30; May = 2) in a simple and efficient way?

Any help would be much appreciated.

 

rainborick

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4343017 posted 1:36 pm on Jul 23, 2011 (gmt 0)

Use mktime() to convert the dates into Unix timestamps, subtract one result from the other and divide by (24 * 60 * 60). Good luck!

astupidname

5+ Year Member



 
Msg#: 4343017 posted 9:31 am on Jul 24, 2011 (gmt 0)

find a simple way for PHP to work out the days for each month when the reservation crosses one or more month ends.

The simplest way is to simply loop from the timestamp of the arrival date to the timestamp of the departure date in intervals of 86400 (number of seconds in a day) being added to the timestamp of the first date, incrementing a counter for the current month and when the month should happen to change add counter for that month and work with it then. Essentially what the below monthDaysBetween function does.
Enjoy:

<?php

function monthDaysBetween($dateA, $dateB) {
$ts1 = strtotime($dateA);
$ts2 = strtotime($dateB);
$a = array();
$month = date('F', $ts1); //string name of month, such as "July"
$year = date('Y', $ts1); //four digit year
$prop = $month.' '.$year;
$a[$prop] = 0;
while ($ts1 < $ts2) {
$a[$prop]++;
$ts1 += 86400; //86400 seconds in a day
$tmpMonth = date('F', $ts1); //string name of month, such as "July"
if ($tmpMonth !== $month) { //we are in to the next month
$month = $tmpMonth;
$year = date('Y', $ts1); //four digit year
$prop = $month.' '.$year;
$a[$prop] = 0;
}
}
return $a; //array of numbers of nights stayed in particular months betweent the two dates
}

//a number of arrays of arrival and departure dates for testing:
$tests = array(
array('arrival' => '2011-03-25', 'departure' => '2011-05-03'),
array('arrival' => '2011/7/24', 'departure' => '2011/7/29'),
array('arrival' => '2011-8-27', 'departure' => '2011-9-3'),
array('arrival' => '2011-03-25', 'departure' => '2012-05-03')
);

foreach ($tests as $arr) {
$arrival = $arr['arrival'];
$departure = $arr['departure'];
$nightsStayed = monthDaysBetween($arrival, $departure);
$totalNights = array_sum($nightsStayed);
echo "<p>Arrive: $arrival, Depart: $departure<br>Total Nights: $totalNights</p>";
echo '<pre>';
print_r($nightsStayed);
echo '</pre><hr>';
}

?>

If anybody's wondering, how to post formatted code on webmasterworld [webmasterworld.com]
Do not copy formatted code on webmasterworld from IE, use other browser such as Firefox.

astupidname

5+ Year Member



 
Msg#: 4343017 posted 1:09 am on Jul 25, 2011 (gmt 0)

Oops, just revisiting this I realized I omitted one thing there. If the departure date falls on the first day of a month then that will put out for example [September 2011] => 0 which we don't want. So at the end of the monthDaysBetween function change this part:
    return $a;

to the following:
    if ($a[$prop] === 0) {
unset($a[$prop]);
}
return $a;


Also, I guess I was being a bit presumptive that a person/persons reading the example may know how to actually access the individual items in the array returned by the monthDaysBetween function. To better show how to do that, change:
    print_r($nightsStayed);

to the following:
    foreach ($nightsStayed as $monthYear => $nights) {
echo $monthYear.' : '.$nights.' nights stayed<br>';
}

Tourex

10+ Year Member



 
Msg#: 4343017 posted 10:28 am on Jul 25, 2011 (gmt 0)

Brilliant!

I had worked out a routine to achieve what I needed, but your routine is around 30% shorter. So, I shall have some fun comparing the two and hopefully learing from it. Thank you!

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved