DJMurtz Posted April 17, 2006 Share Posted April 17, 2006 Hi,Right now I have two dates. One date is (for example) [b]2007-04-15 00:00:00[/b] The other date is the current date. I want to substract the current date from the '2007-04-15 00:00:00' date. I did this by converting both dates to a UNIX timestamp and then substracting them from eachother.Next thing I did was this:[code]<?php $iTimeLeft = strtotime($aMembersInfo['expiredate']) - time(); $iYears = 0; $iDays = 0; $iHours = 0; $iMinutes = 0; $iSeconds = 0; while($iTimeLeft >= 31536000) { $iTimeLeft -= 31536000; $iYears += 1; } while($iTimeLeft >= 86400) { $iTimeLeft -= 86400; $iDays += 1; } while($iTimeLeft >= 3600) { $iTimeLeft -= 3600; $iHours += 1; } while($iTimeLeft >= 60) { $iTimeLeft -= 60; $iMinutes += 1; } if($iTimeLeft >= 0) { $iSeconds = $iTimeLeft; } if($iYears != 0) { $iTimeLeft = $iYears . 'y ' . $iDays . 'd'; } elseif($iDays != 0 && $iDays != 1) { $iTimeLeft = $iDays . 'd'; } elseif($iDays == 1) { $iTimeLeft = $iDays . 'd ' . $iHours . 'h'; } elseif($iHours != 0) { $iTimeLeft = $iHours . 'h ' . $iMinutes . 'm'; } elseif($iMinutes != 0) { $iTimeLeft = $iMinutes . 'm ' . $iSeconds . 's'; } elseif($iSeconds != 0) { $iTimeLeft = $iSeconds . 's'; } else { $iTimeLeft = 'Disabled'; }?>[/code]As you can see I started counting how many years, months, days, hours, minutes and finally seconds fit into the UNIX timestamp I got from substracting the two dates. After this I started putting the number of years, months, etc into their own variables and parse them in the way I want on the screen.All of this works great, with one downside. It's inacurate. As you can see in my code I presume that a month has always 30 days, and a year 365 days. This isn't correct and thus the output is false.I've been trying to think of a way to get the same output, but with correct numbers but have so far found nothing that will help me do this. Does anyone of you know a solution to my problem? I thank you in advance! Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/ Share on other sites More sharing options...
poirot Posted April 17, 2006 Share Posted April 17, 2006 Well, you can use strtotime() to convert "English" dates to UNIX timestamps; then subtract them [a href=\"http://us3.php.net/manual/en/function.strtotime.php\" target=\"_blank\"]http://us3.php.net/manual/en/function.strtotime.php[/a] Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-27898 Share on other sites More sharing options...
DJMurtz Posted April 17, 2006 Author Share Posted April 17, 2006 [!--quoteo(post=365736:date=Apr 18 2006, 01:08 AM:name=poirot)--][div class=\'quotetop\']QUOTE(poirot @ Apr 18 2006, 01:08 AM) [snapback]365736[/snapback][/div][div class=\'quotemain\'][!--quotec--]Well, you can use strtotime() to convert "English" dates to UNIX timestamps; then subtract them [a href=\"http://us3.php.net/manual/en/function.strtotime.php\" target=\"_blank\"]http://us3.php.net/manual/en/function.strtotime.php[/a][/quote]Thanks for the suggestion, but you can see that I already did this in my example..Just to make it more clear:Here I convert everything to UNIX timestamps:$iTimeLeft = strtotime($aMembersInfo['expiredate']) - time();After that I start substracting 31536000 seconds (1 year):while($iTimeLeft >= 31536000) { $iTimeLeft -= 31536000; $iYears += 1;}After that days, hours, minutes and seconds.But as I stated above, this is inacurate, because a year isn't always 365 days and a month isnt always 30 days.I'm on to something tho, I think I figured it out, just making some final tweaks right now Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-27907 Share on other sites More sharing options...
DJMurtz Posted April 17, 2006 Author Share Posted April 17, 2006 After messing around with php I got what I needed:[code]<?php // Calculate time left till deactivation account and echo in cel. // Extract variables from expire date/time $aExpireDate = explode(' ', $aMembersInfo['expiredate']); $aExpireTime = $aExpireDate[1]; $aExpireDate = $aExpireDate[0]; $aExpireDate = explode('-', $aExpireDate); $aExpireTime = explode(':', $aExpireTime); // Extract variables from current date/time $aCurrentDate = explode(' ', $aMembersInfo['now']); $aCurrentTime = $aCurrentDate[1]; $aCurrentDate = $aCurrentDate[0]; $aCurrentDate = explode('-', $aCurrentDate); $aCurrentTime = explode(':', $aCurrentTime); // Calculate differences between now and expire date $iDiffYears = $aExpireDate[0] - $aCurrentDate[0]; $iDiffMonths = $aExpireDate[1] - $aCurrentDate[1]; $iDiffDays = $aExpireDate[2] - $aCurrentDate[2]; $iDiffHours = $aExpireTime[0] - $aCurrentTime[0]; $iDiffMins = $aExpireTime[1] - $aCurrentTime[1]; $iDiffSecs = $aExpireTime[2] - $aCurrentTime[2]; // Make sure correct number of days, months and years are shown if($iDiffDays < 0) { $iDiffMonths--; $iDiffDays += date("t",mktime(0,0,0,date("m")-1)); } if($iDiffMonths < 0) { $iDiffYears--; $iDiffMonths += 12; } // We don't use months, convert them to days while($iDiffMonths != 0) { $iDiffMonths--; $iDiffDays += date("t",mktime(0,0,0,date("m"))); } // Calculate time differences if($iDiffSecs < 0) { $iDiffMins--; $iDiffSecs += 60; } if($iDiffMins < 0) { $iDiffHours--; $iDiffMins += 60; } if($iDiffYears != 0) { $iTimeLeft = $iDiffYears . 'y ' . $iDiffDays . 'd'; } elseif($iDiffDays != 0 && $iDiffDays != 1) { $iTimeLeft = $iDiffDays . 'd'; } elseif($iDiffDays == 1) { $iTimeLeft = $iDiffDays . 'd ' . $iDiffHours . 'h'; } elseif($iDiffHours != 0) { $iTimeLeft = $iDiffHours . 'h ' . $iDiffMins . 'm'; } elseif($iDiffMins != 0) { $iTimeLeft = $iDiffMins . 'm ' . $iDiffSecs . 's'; } elseif($iDiffSecs != 0) { $iTimeLeft = $iDiffSecs . 's'; } if ($iTimeLeft{0} == '-') { $iTimeLeft = 'Disabled'; }?>[/code]Only problem with this method is, it's kind of a processorhog. It took php to parse 10 rows dates with the difference between them via this method [b]0.8 seconds[/b]. Maybe I can find a better way to do what I did in the above script in the future. But for now it works :) Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-27916 Share on other sites More sharing options...
poirot Posted April 17, 2006 Share Posted April 17, 2006 When I get home I'll try to write something, but if I end up with something like this, I'd think it's really not worth the hassle... Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-27928 Share on other sites More sharing options...
poirot Posted April 18, 2006 Share Posted April 18, 2006 I just looked at your first post more carefully, and I really can't think of a good solution.So, can I give you an advice instead? Calculating time left befire expiration is not like "oh my, it must be totally accurate"; if I were a user with more than 1 year of time I wouldn't worry about "hey, its lacking 1 day" or something as long as I know the expiration date itself.So, you should measure the advantages and drawbacks, I would prefer something less accurate over a slow script. Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-27963 Share on other sites More sharing options...
Barand Posted April 18, 2006 Share Posted April 18, 2006 Based on a standard subtraction [code] Y M D H m s-------------------------- 2007 4 15 0 0 0 2006 4 18 0 37 45 ---------------------------- 0 11 26 23 22 15[/code]this processed an array of 10 dates in 0.0016 secs on my server.[code]<?phpfunction getmicrotime(){ list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); }$t1 = getmicrotime();function datediff($exp) { if (strtotime($exp) < time()) { $t1 = getdate(strtotime($exp)); $t2 = getdate(); } else { $t2 = getdate(strtotime($exp)); $t1 = getdate(); } //seconds if ($t2['seconds'] > $t1['seconds']) { $d['seconds'] = $t2['seconds'] - $t1['seconds']; } else { $d['seconds'] = $t2['seconds'] + 60 - $t1['seconds']; $t1['minutes'] += 1; } //minutes if ($t2['minutes'] > $t1['minutes']) { $d['minutes'] = $t2['minutes'] - $t1['minutes']; } else { $d['minutes'] = $t2['minutes'] + 60 - $t1['minutes']; $t1['hours'] += 1; } //hours if ($t2['hours'] > $t1['hours']) { $d['hours'] = $t2['hours'] - $t1['hours']; } else { $d['hours'] = $t2['hours'] + 24 - $t1['hours']; $t1['mday'] += 1; } //days if ($t2['mday'] > $t1['mday']) { $d['mday'] = $t2['mday'] - $t1['mday']; } else { // get days in current month $dim = date('t', mktime(0,0,0,$t1['mon'],1,$t1['year'])); $d['mday'] = $t2['mday'] + $dim - $t1['mday']; $t1['mon'] += 1; } //months if ($t2['mon'] > $t1['mon']) { $d['mon'] = $t2['mon'] - $t1['mon']; } else { $d['mon'] = $t2['mon'] + 12 - $t1['mon']; $t1['year'] += 1; } //years $d['year'] = $t2['year'] - $t1['year']; return array_reverse($d);}$input = array ( '2004-04-15 00:00:00', '2008-05-31 00:00:00', '2007-12-15 00:00:00', '2006-05-31 00:00:00', '2007-04-15 00:00:00', '2006-06-01 00:00:00', '2010-04-15 00:00:00', '2006-09-31 00:00:00', '2007-02-01 00:00:00', '2008-08-08 00:00:00');foreach($input as $dt) { $d = datediff($dt); foreach ($d as $k=>$v) echo "<b>$v</b> $k "; echo '<br>';}$t2 = getmicrotime();echo $t2-$t1;?>[/code] Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-28097 Share on other sites More sharing options...
DJMurtz Posted April 18, 2006 Author Share Posted April 18, 2006 Thanks alot :)That works great, stupid of me not to think of the 'simple math' stuff ;) Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-28178 Share on other sites More sharing options...
DJMurtz Posted April 18, 2006 Author Share Posted April 18, 2006 [!--quoteo(post=366019:date=Apr 18 2006, 04:40 PM:name=Jean M)--][div class=\'quotetop\']QUOTE(Jean M @ Apr 18 2006, 04:40 PM) [snapback]366019[/snapback][/div][div class=\'quotemain\'][!--quotec--]Thanks alot :)That works great, stupid of me not to think of the 'simple math' stuff ;)[/quote]Looking deeper into it it seems your technique is basicly the same as mine.After implementing it it gave me the same slow parse time.After commenting out other lines in the while loop I found the problem (but didn't solve it yet):[code]$aPlanInfo = mysql_fetch_assoc(mysql_query("SELECT term, type FROM plans WHERE id = " . $aMembersInfo['plan']));[/code]I have no clue why a simple query could slow the script down by almost 1 second. I [b]am[/b] testing this localy but I never had this kind of problem before? Could it be that me running the script localy might be causing the delay? Or should I look elsewhere for the problem? Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-28214 Share on other sites More sharing options...
Barand Posted April 18, 2006 Share Posted April 18, 2006 DON'T nest Mysql functions like that.Every time you fetch a row you repeat the query! Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-28279 Share on other sites More sharing options...
DJMurtz Posted April 18, 2006 Author Share Posted April 18, 2006 [!--quoteo(post=366121:date=Apr 18 2006, 08:58 PM:name=Barand)--][div class=\'quotetop\']QUOTE(Barand @ Apr 18 2006, 08:58 PM) [snapback]366121[/snapback][/div][div class=\'quotemain\'][!--quotec--]DON'T nest Mysql functions like that.Every time you fetch a row you repeat the query![/quote]I understand that, but I dont see how else to get the right data for each user, right now I have this:[code] $qMembersInfo = mysql_query("SELECT NOW() AS now, plans.unixtime, plans.id, membership.* FROM membership, plans " . $sWhere . $sWherePlans . " ORDER BY " . $sSortDatabase . " " . $_GET['sort'] . " LIMIT " . $sStart . "," . $sEnd; // Parse selected members in the table. while($aMembersInfo = mysql_fetch_assoc($qMembersInfo)) { // Get plan info for member $aPlanInfo = mysql_fetch_assoc(mysql_query("SELECT term, type FROM plans WHERE id = " . $aMembersInfo['plan'])); }[/code]I don't see another way to get the information I need from the selected user in the while loop... Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-28398 Share on other sites More sharing options...
nogray Posted May 14, 2006 Share Posted May 14, 2006 I notice the solutions where a bit too complicated for this problemtime() function in php will return the number of seconds, so if you have two times and subtract them, you'll get the difference in seconds. All you have to do is convert that into minutes, hours, days, etc...I wrote a small function that will do that[code]function convert_time($seconds){ $f_minutes = $seconds / 60; $i_minutes = floor($f_minutes); $r_seconds = intval(($f_minutes - $i_minutes) * 60); $f_hours = $i_minutes / 60; $i_hours = floor($f_hours); $r_minutes = intval(($f_hours - $i_hours) * 60); $f_days = $i_hours / 24; $i_days = floor($f_days); $r_hours = intval(($f_days - $i_days) * 24); if ($i_days > 0) $r = "$i_days days "; if ($r_hours > 0) $r .= "$r_hours hours "; if ($r_minutes > 0) $r .= "$r_minutes min"; else $r = "less than a minute"; return $r;}[/code]the f_ is for float i_ is for int and r_ is the return value. I only need days, so you can keep going for months and years the same way.Good luck,Wesam Saif[a href=\"http://www.nogray.com\" target=\"_blank\"]http://www.nogray.com[/a] Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-35655 Share on other sites More sharing options...
ryanlwh Posted May 15, 2006 Share Posted May 15, 2006 how do you join the two tables? Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-36002 Share on other sites More sharing options...
bayder Posted August 13, 2006 Share Posted August 13, 2006 Hi,I was playing with the convert_seconds function and found that a value of 46800 to 46859 (13 hours to 13 hours 59 seconds) returns "less than a minute".values above 46859 and values below 46800 return the correct time.This is the only range that I have found and I havent found out why its doing this yet.Does anyone else have this issue?Does anyone see where the problem is?I am using PHP ver. 4.4.2ThanksRay... Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-74237 Share on other sites More sharing options...
bayder Posted August 13, 2006 Share Posted August 13, 2006 I just checked this using the following and there are quite a few values that return less than a minute.[code=php:0]function convert_seconds($seconds){ $f_minutes = $seconds / 60; $i_minutes = floor($f_minutes); $r_seconds = intval(($f_minutes - $i_minutes) * 60); $f_hours = $i_minutes / 60; $i_hours = floor($f_hours); $r_minutes = intval(($f_hours - $i_hours) * 60); $f_days = $i_hours / 24; $i_days = floor($f_days); $r_hours = intval(($f_days - $i_days) * 24); if ($i_days > 0) $r = $i_days."d "; if ($r_hours > 0) $r .= $r_hours."h "; if ($r_minutes > 0) $r .= $r_minutes."m"; else $r = "< a min"; return $r;}$count = 30;while($count < 1000000){ if(convert_seconds($count) == "< a min"){ echo $count; echo "<br />"; } $count = $count + 60;}[/code]Ray... Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-74248 Share on other sites More sharing options...
bayder Posted August 14, 2006 Share Posted August 14, 2006 I found it.The else is only an else for the last if statement I just changed it to if $r is empty.[code=php:0]function convert_seconds($seconds){ $f_minutes = $seconds / 60; $i_minutes = floor($f_minutes); $r_seconds = intval(($f_minutes - $i_minutes) * 60); $f_hours = $i_minutes / 60; $i_hours = floor($f_hours); $r_minutes = intval(($f_hours - $i_hours) * 60); $f_days = $i_hours / 24; $i_days = floor($f_days); $r_hours = intval(($f_days - $i_days) * 24); if ($i_days > 0) $r = "$i_days days "; if ($r_hours > 0) $r .= "$r_hours hours "; if ($r_minutes > 0) $r .= "$r_minutes min"; if ($r == '') $r = "less than a minute"; return $r;}[/code]Ray... Quote Link to comment https://forums.phpfreaks.com/topic/7645-substract-two-dates-and-convert-remaining-time/#findComment-74266 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.