Account Login
 User Name Password Remember Me?
 Latest Articles
 by awuehr on 11-10-2008 in Tips & Tricks by Village Idiot on 11-04-2008 in Classes & Objects by codefreek on 10-23-2008 in Basic by wiifanatic on 09-12-2008 in Security & Permissions by drewbee on 07-03-2008 in Tips & Tricks
 IRC Channel
 Join the friendly bunch on IRC... (#TalkPHP on Freenode) ...Also available via a web interface. See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
 Associates
 Associates
 TalkPHP » Finding the distance between 2 dates...
 LinkBack Thread Tools Search this Thread Display Modes
 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
', \$pDate->inSeconds());printf('Difference: %d minutes
', \$pDate->inMinutes());printf('Difference: %d hours
', \$pDate->inHours());printf('Difference: %d days
', \$pDate->inDays());printf('Difference: %d weeks
', \$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 accordinglyecho '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', \$pDate->inSeconds());printf('Difference: %d minutes', \$pDate->inMinutes());printf('Difference: %d hours', \$pDate->inHours());printf('Difference: %d days', \$pDate->inDays());printf('Difference: %d weeks', \$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:
 sketchMedia (09-01-2008)

 Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 Thread Tools Search this Thread Search this Thread: Advanced Search 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 vB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are On

All times are GMT. The time now is 12:59 AM.

 Contact Us - TalkPHP - PHP Community - Archive - Top

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design