subtracting 1 date from another

  • tommya
  • Graduate
  • Graduate
  • tommya
  • Posts: 221
  • Loc: United Kingdom

Post 3+ Months Ago

i use the following line to set the login date/time for a particular session

Code: [ Select ]
$sesstime = date("Y/m/d H:i:s", time() );


I use a similar line to note the logoff date/time
Is there anyway I can subtract the logon from the logoff, and have it produce how long the user was logged on for?
  • Tannu4u
  • Proficient
  • Proficient
  • User avatar
  • Posts: 480
  • Loc: India

Post 3+ Months Ago

By default PHP has no date difference function here is what u can do


Code: [ Select ]
echo datediff('w', '9 July 2003', '4 March 2004', false)


Code: [ Select ]
function datediff($interval, $datefrom, $dateto, $using_timestamps = false) {
 /*
  $interval can be:
  yyyy - Number of full years
  q - Number of full quarters
  m - Number of full months
  y - Difference between day numbers
   (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".)
  d - Number of full days
  w - Number of full weekdays
  ww - Number of full weeks
  h - Number of full hours
  n - Number of full minutes
  s - Number of full seconds (default)
 */
 
 if (!$using_timestamps) {
  $datefrom = strtotime($datefrom, 0);
  $dateto = strtotime($dateto, 0);
 }
 $difference = $dateto - $datefrom; // Difference in seconds
 
 switch($interval) {
 
  case 'yyyy': // Number of full years

   $years_difference = floor($difference / 31536000);
   if (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom), date("j", $datefrom), date("Y", $datefrom)+$years_difference) > $dateto) {
    $years_difference--;
   }
   if (mktime(date("H", $dateto), date("i", $dateto), date("s", $dateto), date("n", $dateto), date("j", $dateto), date("Y", $dateto)-($years_difference+1)) > $datefrom) {
    $years_difference++;
   }
   $datediff = $years_difference;
   break;

  case "q": // Number of full quarters

   $quarters_difference = floor($difference / 8035200);
   while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($quarters_difference*3), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
    $months_difference++;
   }
   $quarters_difference--;
   $datediff = $quarters_difference;
   break;

  case "m": // Number of full months

   $months_difference = floor($difference / 2678400);
   while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
    $months_difference++;
   }
   $months_difference--;
   $datediff = $months_difference;
   break;

  case 'y': // Difference between day numbers

   $datediff = date("z", $dateto) - date("z", $datefrom);
   break;

  case "d": // Number of full days

   $datediff = floor($difference / 86400);
   break;

  case "w": // Number of full weekdays

   $days_difference = floor($difference / 86400);
   $weeks_difference = floor($days_difference / 7); // Complete weeks
   $first_day = date("w", $datefrom);
   $days_remainder = floor($days_difference % 7);
   $odd_days = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder?
   if ($odd_days > 7) { // Sunday
    $days_remainder--;
   }
   if ($odd_days > 6) { // Saturday
    $days_remainder--;
   }
   $datediff = ($weeks_difference * 5) + $days_remainder;
   break;

  case "ww": // Number of full weeks

   $datediff = floor($difference / 604800);
   break;

  case "h": // Number of full hours

   $datediff = floor($difference / 3600);
   break;

  case "n": // Number of full minutes

   $datediff = floor($difference / 60);
   break;

  default: // Number of full seconds (default)

   $datediff = $difference;
   break;
 }  

 return $datediff;

}
  1. function datediff($interval, $datefrom, $dateto, $using_timestamps = false) {
  2.  /*
  3.   $interval can be:
  4.   yyyy - Number of full years
  5.   q - Number of full quarters
  6.   m - Number of full months
  7.   y - Difference between day numbers
  8.    (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".)
  9.   d - Number of full days
  10.   w - Number of full weekdays
  11.   ww - Number of full weeks
  12.   h - Number of full hours
  13.   n - Number of full minutes
  14.   s - Number of full seconds (default)
  15.  */
  16.  
  17.  if (!$using_timestamps) {
  18.   $datefrom = strtotime($datefrom, 0);
  19.   $dateto = strtotime($dateto, 0);
  20.  }
  21.  $difference = $dateto - $datefrom; // Difference in seconds
  22.  
  23.  switch($interval) {
  24.  
  25.   case 'yyyy': // Number of full years
  26.    $years_difference = floor($difference / 31536000);
  27.    if (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom), date("j", $datefrom), date("Y", $datefrom)+$years_difference) > $dateto) {
  28.     $years_difference--;
  29.    }
  30.    if (mktime(date("H", $dateto), date("i", $dateto), date("s", $dateto), date("n", $dateto), date("j", $dateto), date("Y", $dateto)-($years_difference+1)) > $datefrom) {
  31.     $years_difference++;
  32.    }
  33.    $datediff = $years_difference;
  34.    break;
  35.   case "q": // Number of full quarters
  36.    $quarters_difference = floor($difference / 8035200);
  37.    while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($quarters_difference*3), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
  38.     $months_difference++;
  39.    }
  40.    $quarters_difference--;
  41.    $datediff = $quarters_difference;
  42.    break;
  43.   case "m": // Number of full months
  44.    $months_difference = floor($difference / 2678400);
  45.    while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
  46.     $months_difference++;
  47.    }
  48.    $months_difference--;
  49.    $datediff = $months_difference;
  50.    break;
  51.   case 'y': // Difference between day numbers
  52.    $datediff = date("z", $dateto) - date("z", $datefrom);
  53.    break;
  54.   case "d": // Number of full days
  55.    $datediff = floor($difference / 86400);
  56.    break;
  57.   case "w": // Number of full weekdays
  58.    $days_difference = floor($difference / 86400);
  59.    $weeks_difference = floor($days_difference / 7); // Complete weeks
  60.    $first_day = date("w", $datefrom);
  61.    $days_remainder = floor($days_difference % 7);
  62.    $odd_days = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder?
  63.    if ($odd_days > 7) { // Sunday
  64.     $days_remainder--;
  65.    }
  66.    if ($odd_days > 6) { // Saturday
  67.     $days_remainder--;
  68.    }
  69.    $datediff = ($weeks_difference * 5) + $days_remainder;
  70.    break;
  71.   case "ww": // Number of full weeks
  72.    $datediff = floor($difference / 604800);
  73.    break;
  74.   case "h": // Number of full hours
  75.    $datediff = floor($difference / 3600);
  76.    break;
  77.   case "n": // Number of full minutes
  78.    $datediff = floor($difference / 60);
  79.    break;
  80.   default: // Number of full seconds (default)
  81.    $datediff = $difference;
  82.    break;
  83.  }  
  84.  return $datediff;
  85. }
  • Axe
  • Genius
  • Genius
  • User avatar
  • Posts: 5739
  • Loc: Sub-level 28

Post 3+ Months Ago

That seems like a lot of code for a simple function...

Why not just use the strtotime() function, subtract one from the other. This will give you a time difference in seconds.

Just divide by 60 to get minutes, divide by 3600 for hours, divide by 86400 for days.

PHP Code: [ Select ]
<?php
 
 
 
$nowdate = strtotime("4 March 2004");
 
$thendate = strtotime("9 July 2003");
 
 
 
$datediff = ($nowdate - $thendate);
 
 
 
echo $datediff." Seconds<br>";
 
echo round($datediff / 60)." Minutes<br>";
 
echo round($datediff / 3600)." Hours<br>";
 
echo round($datediff / 86400)." Days<br>";
 
 
 
?>
  1. <?php
  2.  
  3.  
  4.  
  5. $nowdate = strtotime("4 March 2004");
  6.  
  7. $thendate = strtotime("9 July 2003");
  8.  
  9.  
  10.  
  11. $datediff = ($nowdate - $thendate);
  12.  
  13.  
  14.  
  15. echo $datediff." Seconds<br>";
  16.  
  17. echo round($datediff / 60)." Minutes<br>";
  18.  
  19. echo round($datediff / 3600)." Hours<br>";
  20.  
  21. echo round($datediff / 86400)." Days<br>";
  22.  
  23.  
  24.  
  25. ?>
  • tommya
  • Graduate
  • Graduate
  • tommya
  • Posts: 221
  • Loc: United Kingdom

Post 3+ Months Ago

that last function looks great, ideal in fact but will that work with the format my dates are in?
  • b_heyer
  • Web Master
  • Web Master
  • User avatar
  • Posts: 4581
  • Loc: Maryland

Post 3+ Months Ago

Not sure... http://www.php.net/manual/en/function.strtotime.php
  • Scorpius
  • Proficient
  • Proficient
  • User avatar
  • Posts: 401
  • Loc: Scorpion Hole

Post 3+ Months Ago

You should just leave your dates as timestamps until you display them, then they are easily add, subtracted and everything in between.
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Posts: 1855
  • Loc: Uk

Post 3+ Months Ago

tommya wrote:
Code: [ Select ]
$sesstime = date("Y/m/d H:i:s", time() );


Like scorpiux says, just use the timestamp, why make things difficult for yourself?

Code: [ Select ]
$sesstime = time();


If you want to work with times and date in code then they do not <b>need</b> to be formatted. Only format them when a human needs to read it. Same goes for storing dates in a database, what is the point of storing a formatted string?

Computers work with <b>data</b>, humans work better with information:
a timestamp is data
the string "2004/07/05 09:56:27" is information

Therefore the timestamp is the most appropriate for a computer, the string for a human.
  • tommya
  • Graduate
  • Graduate
  • tommya
  • Posts: 221
  • Loc: United Kingdom

Post 3+ Months Ago

so are you saying that

Code: [ Select ]
$sesstime = time();


is actually the same as I was doing anyway, but I was doing it in a more complicated way?
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Posts: 1855
  • Loc: Uk

Post 3+ Months Ago

well yeah.

your method:
Code: [ Select ]
Get Current Time
Format Current Time
Save formatted current time as $sesstime
.......
retreive $sesstime
Unformat $sesstime
process sesstime
  1. Get Current Time
  2. Format Current Time
  3. Save formatted current time as $sesstime
  4. .......
  5. retreive $sesstime
  6. Unformat $sesstime
  7. process sesstime


Alternative:
Code: [ Select ]
Get Current Time
Save current time as $sesstime
.......
retreive $sesstime
process sesstime
  1. Get Current Time
  2. Save current time as $sesstime
  3. .......
  4. retreive $sesstime
  5. process sesstime


All you have done is added in an extra two processes that in reality do nothing.
  • tomkast
  • Born
  • Born
  • tomkast
  • Posts: 1

Post 3+ Months Ago

good idea from axe. but math is wrong. you need:

$duration = strtotime($date1) - strtotime($date2;

$second = $duration%60;
$minute = (($duration-$second)/60)%60;
$hour = (($duration-$second)-($minute*60))/3600;

you don't need round(), modulo operator takes care of that...

then if you want to show the time interval nice with leading zeros, try:

echo date("H:i:s", strtotime($hour . ":" . $minute . ":" . $second));
  • righteous_trespasser
  • Scuffle
  • Genius
  • User avatar
  • Posts: 6230
  • Loc: South-Africa

Post 3+ Months Ago

tomkast, that thread is over four years old ... I think it's safe to assume that this thread is resolved ...
  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8413
  • Loc: USA

Post 3+ Months Ago

Just out of topic question and yet not all that important to start a thread for it's own... how do you format a timestamp like how rtm223 described?
  • mishka
  • Novice
  • Novice
  • mishka
  • Posts: 20
  • Loc: Toronto

Post 3+ Months Ago

I'm using this a lot ... thought to be honest I'm not the author

/**
* Return number of day between 2 dates
* @param string $date1 Date to compare
* @param string $date2 Date to compare
* @access public
**/
function diff_date($date1, $date2){
$an = substr("$date1", 0, 4);
$mois = substr("$date1", 5, 2);
$jour = substr("$date1", 8, 2);

$an2 = substr("$date2", 0, 4);
$mois2 = substr("$date2", 5, 2);
$jour2 = substr("$date2", 8, 2);

$timestamp = mktime(0, 0, 0, $mois, $jour, $an);
$timestamp2 = mktime(0, 0, 0, $mois2, $jour2, $an2);
$diff = floor(($timestamp - $timestamp2) / (3600 * 24));
return $diff;
}
  • goggles
  • Born
  • Born
  • goggles
  • Posts: 1
  • Loc: Virginia, USA

Post 3+ Months Ago

Tannu4u you are the man, thank you very much. your script is very flexible & can be used for many things.

I am currently building an outage message database, w/ email support. & I needed a way to see how long the outage was (I work for a ISP).

This is how I have used Tannu4u's script.


// breaks down into weeks, days, hr's, months, min's....
$weeks = datediff ("ww", $datefrom, $dateto);
$days = datediff ("d", $datefrom, $dateto);
$hrs = datediff ("h", $datefrom, $dateto);
$mins = datediff ("n", $datefrom, $dateto);
$day_diff = $days - ($weeks * 7);
$hr_diff = $hrs - ($days * 24);
$min_diff = $mins - ($hrs * 60);

$duration = "";
function duration ($period, $print)
{
global $duration;
if ($period >= 1)
{
$duration .= " ". $period ." $print";
}
if ($period > 1)
{
$duration .= "\'s";
}
}

duration ($weeks, "Week");
duration ($day_diff, "Day");
duration ($hr_diff, "Hr");
duration ($min_diff, "Min");



echo "duration = $duration";

Post Information

  • Total Posts in this topic: 14 posts
  • Users browsing this forum: No registered users and 74 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.