TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble 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
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 05-27-2008, 10:51 PM   #1 (permalink)
may
The Wanderer
 
may's Avatar
 
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
may is on a distinguished road
Help 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...
may is offline  
Reply With Quote
Old 05-27-2008, 11:03 PM   #2 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

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.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 05-28-2008, 06:07 AM   #3 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
ReSpawN is on a distinguished road
Default

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(000$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.
Send a message via MSN to ReSpawN
ReSpawN is offline  
Reply With Quote
Old 05-28-2008, 12:53 PM   #4 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

@up- So why do you use sEndDate ? You don't even use it anywhere xD
__________________
Tanax is offline  
Reply With Quote
Old 05-28-2008, 05:29 PM   #5 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
ReSpawN is on a distinguished road
Default

There you go.
__________________
"Life is a bitch, take that bitch on a ride"
Send a message via MSN to ReSpawN
ReSpawN is offline  
Reply With Quote
Old 05-28-2008, 07:15 PM   #6 (permalink)
may
The Wanderer
 
may's Avatar
 
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
may is on a distinguished road
Default

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...
may is offline  
Reply With Quote
Old 05-28-2008, 09:10 PM   #7 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

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.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 05-28-2008, 09:25 PM   #8 (permalink)
The Frequenter
 
ReSpawN's Avatar
 
Join Date: Nov 2007
Location: Netherlands
Posts: 460
Thanks: 49
ReSpawN is on a distinguished road
Default

You can use the DATE() function in mySQL though.
__________________
"Life is a bitch, take that bitch on a ride"
Send a message via MSN to ReSpawN
ReSpawN is offline  
Reply With Quote
Old 05-28-2008, 09:43 PM   #9 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

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
delayedinsanity is offline  
Reply With Quote
Old 05-28-2008, 10:50 PM   #10 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

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.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 05-28-2008, 11:01 PM   #11 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

Show off.

Excellent example of using __call() though.
-m
delayedinsanity is offline  
Reply With Quote
Old 05-29-2008, 12:07 AM   #12 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

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).
Salathe is offline  
Reply With Quote
Old 05-29-2008, 10:16 AM   #13 (permalink)
may
The Wanderer
 
may's Avatar
 
Join Date: May 2008
Location: Netherlands
Posts: 5
Thanks: 0
may is on a distinguished road
Default

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...
may is offline  
Reply With Quote
Old 05-29-2008, 12:14 PM   #14 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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
sketchMedia is offline  
Reply With Quote
Old 05-29-2008, 01:43 PM   #15 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-29-2008, 02:01 PM   #16 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

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');.
Salathe is offline  
Reply With Quote
Old 05-29-2008, 02:06 PM   #17 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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
sketchMedia is offline  
Reply With Quote
Old 05-29-2008, 02:55 PM   #18 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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
sketchMedia is offline  
Reply With Quote
Old 06-08-2008, 04:01 AM   #19 (permalink)
The Addict
 
Enfernikus's Avatar
 
Join Date: Jun 2008
Posts: 335
Thanks: 2
Enfernikus is on a distinguished road
Default

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.
Enfernikus is offline  
Reply With Quote
The Following User Says Thank You to Enfernikus For This Useful Post:
sketchMedia (09-01-2008)
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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 Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 03:55 AM.

 
     

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