 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
 |
|
 |
05-27-2008, 10:51 PM
|
#1 (permalink)
|
|
The Wanderer
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
|
Finding the distance between 2 dates...
Hi all.
Im trying to find a method (if there is any) that can calculate the distance in days, months or years between two dates. Mainly the distance in days. i almost searched the whole datetime object to no afail...
So for example i have 2008-05-29 and 2008-06-01 i would like to find the distance in days for instance which should be 3. or in months wich should be 1 or years that should be 0.
Usually i use mysql to solve this little math problem, but i was wondering if there isnt a php method that could calculate this instead of using de expensive sql connection all the time to solve it...
Hope its kinda clear what i mean...
Thanks in advance,
May
__________________
Uhm 1^2+1^2=3^10 or something like that...
|
|
|
|
05-27-2008, 11:03 PM
|
#2 (permalink)
|
|
La Vida es Sueño
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
|
php Code:
$iStartDate = '2008-05-29'; $iEndDate = '2008-06-01'; printf( 'Distance between 2 dates is %d days.', (strtotime($iEndDate) - strtotime($iStartDate)) / 86400);
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
|
|
|
05-28-2008, 06:07 AM
|
#3 (permalink)
|
|
The Frequenter
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
|
Although Adam's way is more thorough, you might want to use this.
PHP Code:
$sStartDate = explode('-', '2008-05-29'); // $sEndDate = explode('-', '2008-06-01'); Tanax got mad.
/* Now you would have something like $sStartDate[0]; would be 2008, being 1, 05 and 2, 29th.
Now, you could make a timestamp which I always use, it's more easier on the eyes if you ask me. */
$iStartDate = mktime(0, 0, 0, $sStartDate[1], $sStartDate[2], $sStartDate[0]);
/* Now, with that b-e-a-utiful function, you would recieve a timestamp which you can use almost anywhere. If you want to push a date onto the screen, use this. */
echo date('H:i:s d-m-Y', $iStartDate);
/* Note: I didn't try it, scripted it into this quickreply so there MIGHT be some errors - off to school now. */
Oh yes, $iStartDate being that it's a TOTAL integer (only numbers), and $sStartDate, being that it contains a dash which is not a numeric function, if checked with the is_numeric function. 
__________________
"Life is a bitch, take that bitch on a ride"
Last edited by ReSpawN : 05-28-2008 at 05:29 PM.
|
|
|
05-28-2008, 12:53 PM
|
#4 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
@up- So why do you use sEndDate ? You don't even use it anywhere xD
__________________
|
|
|
|
05-28-2008, 05:29 PM
|
#5 (permalink)
|
|
The Frequenter
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
|
There you go.
__________________
"Life is a bitch, take that bitch on a ride"
|
|
|
05-28-2008, 07:15 PM
|
#6 (permalink)
|
|
The Wanderer
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
|
Hehe thanks guys for solving this using pure math. Im sure i can put it to use at some point so thx for that :D
But still there isnt a method out there that actually solves this within an php function like Mysql can using DATEDIFF('expr1', 'expr2')?
__________________
Uhm 1^2+1^2=3^10 or something like that...
|
|
|
|
05-28-2008, 09:10 PM
|
#7 (permalink)
|
|
La Vida es Sueño
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
|
I'm unaware of any such function. Maybe there is one in-built though, but I somehow doubt it as it's quite basic mathematics.
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
|
|
|
05-28-2008, 09:25 PM
|
#8 (permalink)
|
|
The Frequenter
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
|
You can use the DATE() function in mySQL though.
__________________
"Life is a bitch, take that bitch on a ride"
|
|
|
05-28-2008, 09:43 PM
|
#9 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Wildhoney, I apologize in advance if stealing.. er, borrowing your code is in any way offensive, but just for clarity's sake;
PHP Code:
function dateDiff ($iStartDate, $iEndDate) { return sprintf('%d', (strtotime($iEndDate) - strtotime($iStartDate)) / 86400); }
$iDiff = dateDiff('2008-05-29', '2008-06-01'); echo "Distance between two dates is {$iDiff} days.";
now you have a function that does it.  If it's not built in, but you know how to do it (or somebody shows you), you can make a function and use it as much as you like.
-m
|
|
|
|
05-28-2008, 10:50 PM
|
#10 (permalink)
|
|
La Vida es Sueño
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
|
That's quite OK! How about the following?
php Code:
class DateDiff { private $m_pDates; private $m_aConversions; public function __construct($iStartDate, $iEndDate) { $this-> m_aConversions = array ( 'Seconds' => 0, 'Minutes' => 60, 'Hours' => 3600, 'Days' => 86400, 'Weeks' => 604800 ); $this-> m_pDates-> start = $iStartDate; $this-> m_pDates-> end = $iEndDate; } public function __call($szCall, $aArgs) { if(! preg_match('~^in(.+)~', $szCall, $aMatches)) { throw new Exception ('Invalid conversion format supplied.'); } $szCall = $aMatches[ 1]; if (! in_array($szCall, $this-> m_aConversions)) { throw new Exception ('Specified conversion is not available.'); } if($this-> m_aConversions[ $szCall] == 0) { return strtotime($this-> m_pDates-> end) - strtotime($this-> m_pDates-> start); } return(strtotime($this-> m_pDates-> end) - strtotime($this-> m_pDates-> start)) / $this-> m_aConversions[ $szCall]; }}
Then we can use it like so:
php Code:
$pDate = new DateDiff ('2008-05-29', '2008-06-01'); printf('Difference: %d seconds<br />', $pDate-> inSeconds()); printf('Difference: %d minutes<br />', $pDate-> inMinutes()); printf('Difference: %d hours<br />', $pDate-> inHours()); printf('Difference: %d days<br />', $pDate-> inDays()); printf('Difference: %d weeks<br />', $pDate-> inWeeks());
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
|
|
|
05-28-2008, 11:01 PM
|
#11 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Show off.
Excellent example of using __call() though.
-m
|
|
|
|
05-29-2008, 12:07 AM
|
#12 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
How about calculating the correct answers when a daylight savings boundary is crossed? For example, at the moment, the code will return 0 days between March 30th and 31st this year (for timezone Europe/London).
|
|
|
|
05-29-2008, 10:16 AM
|
#13 (permalink)
|
|
The Wanderer
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
|
Hehehe is it me? or are subjects always treated this thurally?
Btw great examples there :)
ow and... :P
When do we cross the point that we are actually discussing how to handle leap years and the so much discussed 4000 Years rule in the gregorian calendar? (not hoping my code wil ever run that long :P) Hehe.
Anywayz thanks in advanced for the comments on this subject :D
regards,
__________________
Uhm 1^2+1^2=3^10 or something like that...
|
|
|
|
05-29-2008, 12:14 PM
|
#14 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
i think you can use the date function to output the timezone offset in seconds by using the 'Z' param:
PHP Code:
echo date('Z');
or using the DateTime object:
PHP Code:
$dstOffset = new DateTime(); echo $dstOffset->getOffset();
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
Last edited by sketchMedia : 05-29-2008 at 12:15 PM.
Reason: syntax error
|
|
|
|
05-29-2008, 01:43 PM
|
#15 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
I think this should do it, there is probably a better way of doing it but it works for me:
PHP Code:
$date = '30-03-2008'; $date2 = '31-03-2008';
//get the offset $dateTime1 = new DateTime($date); $dateTime2 = new DateTime($date2); $dstZone = new DateTimeZone('Europe/London');//change accordingly
echo 'Difference: ',((strtotime($date2) + $dstZone->getOffset($dateTime2)) - (strtotime($date) + $dstZone->getOffset($dateTime1))) / 86400, ' Days';
outputs: 1 day.
edit: i think this is for php 5.2.x not sure about 5.1.x as i dunno when these classes were added, any1 know?
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-29-2008, 02:01 PM
|
#16 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
sketch, try that with some other timezone settings applied to the DateTime objects. For example, at the top of the script call date_default_timezone_set('Asia/Tokyo');.
|
|
|
|
05-29-2008, 02:06 PM
|
#17 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
with the date_default_timezone_set('Asia/Tokyo')
set it outputs:
1.04166666667
but if you also change
PHP Code:
DateTimeZone('Europe/London')
to
PHP Code:
DateTimeZone('Asia/Tokyo')
it calculates the correct offset for Asia/Tokyo instead of Europe/London and thus out puts 1 day correctly.
this should do it automatically:
PHP Code:
date_default_timezone_set('Asia/Tokyo'); $date = '05-03-2008'; $date2 = '10-03-2008'; $dstZone = new DateTimeZone(date_default_timezone_get()); echo 'Difference: ',((strtotime($date2) + $dstZone->getOffset(new DateTime($date2))) - (strtotime($date) + $dstZone->getOffset(new DateTime($date)))) / 86400, ' Days';
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
Last edited by sketchMedia : 05-29-2008 at 02:18 PM.
Reason: pasted incorrect code
|
|
|
|
05-29-2008, 02:55 PM
|
#18 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
Combined into Wildhoney's class (which i have slightly modified, i added 'array_key_exists, instead of 'in_array' and a few small things)
PHP Code:
class DateDiff { private $m_pDates; private $m_aConversions; public function __construct($iStartDate, $iEndDate, $szTimeZone = '') { $this->m_aConversions = array ( 'Seconds' => 0, 'Minutes' => 60, 'Hours' => 3600, 'Days' => 86400, 'Weeks' => 604800 ); $pDateTimezone = new DateTimeZone( (!empty($szTimeZone)) ? $szTimeZone : date_default_timezone_get() ); //get time and add related offsets(if any)
$this->m_pDates->start = strtotime($iStartDate) + $pDateTimezone->getOffset(new DateTime($iStartDate)); $this->m_pDates->end = strtotime($iEndDate) + $pDateTimezone->getOffset(new DateTime($iEndDate)); } public function __call($szCall, $aArgs) { if(!preg_match('~^in(.+)~', $szCall, $aMatches)) { throw new Exception('Invalid conversion format supplied.'); } $szCall = $aMatches[1]; if (!array_key_exists($szCall, $this->m_aConversions)) { throw new Exception('Specified conversion is not available.'); } if($this->m_aConversions[$szCall] == 0) { return $this->m_pDates->end - $this->m_pDates->start; } return ($this->m_pDates->end - $this->m_pDates->start) / $this->m_aConversions[$szCall]; } }
Now we can:
PHP Code:
date_default_timezone_set('Asia/Tokyo');
$pDate = new DateDiff('2008-01-29', '2008-01-30'); printf('Difference: %d seconds<br />', $pDate->inSeconds()); printf('Difference: %d minutes<br />', $pDate->inMinutes()); printf('Difference: %d hours<br />', $pDate->inHours()); printf('Difference: %d days<br />', $pDate->inDays()); printf('Difference: %d weeks<br />', $pDate->inWeeks());
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
Last edited by sketchMedia : 05-30-2008 at 08:27 AM.
Reason: made code smaller
|
|
|
|
06-08-2008, 04:01 AM
|
#19 (permalink)
|
|
The Addict
Join Date: Jun 2008
Posts: 335
Thanks: 2
|
I just want to point out something in the above classes
PHP Code:
if($this->m_aConversions[$szCall] == 0) { return $this->m_pDates->end - $this->m_pDates->start; }
If you just change the seconds in the conversions array to 1 you don't need the above line of code as X/1 = X or if you don't like algebra - a number over one will always be that number.
|
|
|
|
|
The Following User Says Thank You to Enfernikus For This Useful Post:
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Hybrid Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|