This question already has answers here:
How to get time difference in minutes in PHP
(21 answers)
Closed 9 years ago.
I have a simple function below that gets seconds and returns it like "2 minutes ago", "9 hours ago" etc...
if I pass 1 on 'relativedate()' function it will just return 1 sec and so on. As we all know 60*60*24*7*30 or 18144000sec = 1 month. Therefore if I pass a value of 18144000 on the parameter, it should return 1 month.However, if I pass a value on the parameter lets say 231440000 on relativedate() which should be more than a year, it is returning '13 months' instead of 1 year.
function relativedate($secs) {
$second = 1;
$minute = 60;
$hour = 60*60;
$day = 60*60*24;
$week = 60*60*24*7;
$month = 60*60*24*7*30;
$year = 60*60*24*7*30*365;
if ($secs <= 0) { $output = "now";
}elseif ($secs > $second && $secs < $minute) { $output = round($secs/$second)." second";
}elseif ($secs >= $minute && $secs < $hour) { $output = round($secs/$minute)." minute";
}elseif ($secs >= $hour && $secs < $day) { $output = round($secs/$hour)." hour";
}elseif ($secs >= $day && $secs < $week) { $output = round($secs/$day)." day";
}elseif ($secs >= $week && $secs < $month) { $output = round($secs/$week)." week";
}elseif ($secs >= $month && $secs < $year) { $output = round($secs/$month)." month";
}elseif ($secs >= $year && $secs < $year*10) { $output = round($secs/$year)." year";
}else{ $output = " more than a decade ago"; }
if ($output <> "now"){
$output = (substr($output,0,2)<>"1 ") ? $output."s" : $output;
}
return $output;
}
echo relativedate(60); // 1 minute
Your year calculation is for 365 Months, not 12 months
Related
I'm working on a calendar for my office. Every people has his own column and there is a line for every day.
There are some periodic date, where, for example, given people have to be working on the week-end. But most of the dates are coming from a MySQL database.
So it does a double loop (people vs dates) in which every dates have to be check for the person, what kind of occupation he has on this day.
Is there a way to optimize this script, because online it take at least 2-3 seconds (only 0.03 seconds according to PHP, but I don't feel like it's correct) and more than 8 seconds (again according to PHP) on our network! And this is just for 5 months, we'd like to have it for the whole year.
You can find a test version here (just to see the HTML and CSS): http://mybees.ch/for/tableau.php
And here is the PHP in it:
//Creating the line for the collaborators
$ids;
$ma_count=0;
$ma_name_query = mysqli_query($bdi,"SELECT DISTINCT m.id, m.name, m.vorname, m.grup FROM ma m, ma_pos mp WHERE m.id = mp.maid AND m.grup != 14 ORDER BY m.grup, mp.posid, m.name, m.vorname");
while($ma_name = mysqli_fetch_assoc($ma_name_query)) {
echo '<div class="cell name">'.$ma_name['name'].' '.$ma_name['vorname'].'</div>';
$ids[$ma_count] = $ma_name['id'];
$grup[$ma_count] = $ma_name['grup'];
$ma_count++;
}
// Check if special group day
$firstGroup = 1;
$firstDate = strtotime("$year-01-01 00:00 GMT");
$picket = array();
if (date("N", $firstDate) == 2)// Tuesday
$firstDate -= 24 * 3600;
elseif (date("N", $firstDate) == 3)// Wednesday
$firstDate -= 2 * 24 * 3600;
elseif (date("N", $firstDate) == 5)// Friday
$firstDate -= 24 * 3600;
elseif (date("N", $firstDate) == 6)// Saturday
$firstDate -= 2 * 24 * 3600;
elseif (date("N", $firstDate) == 7)// Sunday
$firstDate -= 3 * 24 * 3600;
for ($date = $firstDate; $date <= strtotime("$year-12-31 00:00 GMT"); $date += 24 * 3600) {
$weekNb = date("W",$date);
$weekDay = date("N",$date); // Monday = 1, Sunday = 7
if ($weekDay < 4)
$group = $weekNb % 4 - 1 + $firstGroup;
else
$group = $weekNb % 4 - 2 + $firstGroup;
if ($group == 0)
$group = 4;
if ($group == -1)
$group = 3;
$picket[$date] = $group;
}
$groupColor = ["yellow", "blue", "red", "green"];
function isPicket($date, $grup) {
global $picket, $groupColor;
//global $picket, $groupColor;
if ($grup < 5) {
if ($picket[$date] == $grup)
return " style='background-color: ".$groupColor[$picket[$date]-1]."'";
}
}
$today_stp = time() - time() % (24 * 3600) - 11 * 24 * 3600;
$frei_query_text = "SELECT id_ma, date1, date2, free.id as type, moment, remark, location FROM frei, free WHERE free.id = frei.type AND date1 BETWEEN CAST('$date1' AS DATE) AND CAST('$date2' AS DATE)";
$frei_query = mysqli_query($bdi, $frei_query_text);
$free = array();
while($frei = mysqli_fetch_assoc($frei_query)) {
$free[] = $frei;
}
// Filling the lines
for ($date = strtotime($date1); $date <= strtotime($date2); $date += 24 * 3600) {
$today = ($date == $today_stp) ? ' id="today"':'';
echo "<div class='clear'$today>";
$class = (date('N', $date) < 6) ? 'week' : 'weekend';
echo "<div class='date $class line'>".date("D, d.m.", $date)."</div>";
for ($i = 0; $i < $ma_count; $i++) {
echo "<div class='cell line $class'".isPicket($date,$grup[$i]).">
<div class='small-cell".isColor($ids[$i], $date, 0)."' id='divUp-".$ids[$i]."-$date'> </div>
<div class='small-cell".isColor($ids[$i], $date, 1)."' id='divDown-".$ids[$i]."-$date'> </div>
</div>";
}
echo '</div>';
}
function isColor($id_ma, $date, $moment) {
global $free;
for ($i = 0; $i < count($free); $i++) {
if ($id_ma == $free[$i]['id_ma']) {
if ($date >= strtotime($free[$i]['date1']) && $date <= strtotime($free[$i]['date2'])) {
if ($free[$i]['moment'] == $moment || $free[$i]['moment'] == 2) {
$type = $free[$i]['type'];
$style = "";
if ($type > 1 && $type < 5)
$style = " urlaub";
if ($type > 4 && $type < 8)
$style = " frei";
if ($type > 7 && $type < 11)
$style = " ferien";
if (($type > 22 && $type < 34) || ($type > 37 && $type < 48))
$style = " kurse";
if ($type > 10 && $type < 17)
$style = " krank";
return " $style' title='".$free[$i]['remark'];
}
}
}
}
}
Thank you very much for your help
I have a simple script that will dynamically convert minutes into minutes, hours and days dynamically( Meaning if I have 1 minute, the script will put put "1 Minute", and if I have 61 mins, the script will say "1 Hour and 1 Minute" etc. with the proper grammar). Basically, although I try to set the value of a variable as an int, my current time (112 mins) comes out as: 1.8666666666667 Hours and 52 Minutes.
settype($otime, "integer");
settype($hours, "integer");
settype($mins, "integer");
settype($hour, "integer");
if($otime == 1) {
$otime = "1 Minute";
}else if($otime < 60 && $otime !=1) {
$otime = $otime." Minutes";
}
else if($otime >= 60 && $otime < 1440) {
$hours = $otime / 60;
$mins = $otime % 60;
if($mins == 1 && $hours != 1) {
$otime = $hours." Hours and ".$mins." Minute";
}
else if($mins != 1 && $hours == 1) {
$otime = $hours." Hour and ".$mins." Minutes";
}
else if($mins == 1 && $hours == 1) {
$otime = $hours." Hour and ".$mins." Minute";
}
else {
$otime = $hours." Hours and ".$mins." Minutes";
}
}
else if($otime >= 1440) {
$days = $otime / 1440;
$hour = $otime % 1440;
$hours = $hour / 60;
$mins = $hour % 60;
if($days == 1 && $hours != 1 && $mins != 1) {
$otime = $days." Day ".$hours." Hours and ".$mins." Minutes";
}
if($days != 1 && $hours == 1 && $mins != 1) {
$otime = $days." Days ".$hours." Hour and ".$mins." Minutes";
}
if($days != 1 && $hours != 1 && $mins == 1) {
$otime = $days." Days ".$hours." Hours and ".$mins." Minute";
}
if($days == 1 && $hours == 1 && $mins != 1) {
$otime = $days." Day ".$hours." Hour and ".$mins." Minutes";
}
if($days == 1 && $hours == 1 && $mins == 1) {
$otime = $days." Day ".$hours." Hour and ".$mins." Minute";
}
if($days != 1 && $hours == 1 && $mins == 1) {
$otime = $days." Days ".$hours." Hour and ".$mins." Minute";
}
if($days == 1 && $hours != 1 && $mins == 1) {
$otime = $days." Day ".$hours." Hours and ".$mins." Minute";
}
if($days != 1 && $hours != 1 && $mins != 1) {
$otime = $days." Days ".$hours." Hours and ".$mins." Minutes";
}
}
Also - Is there a simpler way to do this? and did I miss any if's (For grammar purposes)
Try something like this :
echo gmdate("H:i:s", ($minutes * 60));
Or with a function DateTime() :(Thanks to #Ryan Kempt)
function minutesToTime($minutes) {
$minutes = $minutes * 60;
$dtF = new DateTime("#0");
$dtT = new DateTime("#$minutes");
if($dtF->diff($dtT)->format('%i') !=0 ){
$min = ($dtF->diff($dtT)->format('%i') == 1 ? ' %i Minute' : ' %i Minutes');
}
else{
$min = '';
}
if($dtF->diff($dtT)->format('%h') !=0 ){
$hours = ($dtF->diff($dtT)->format('%h') == 1 ? ' %h Hour' : ' %h Hours');
}
else{
$hours = '';
}
if($dtF->diff($dtT)->format('%a') !=0 ){
$days = ($dtF->diff($dtT)->format('%a') == 1 ? ' %a Day' : ' %a Days');
}
else{
$days = '';
}
if($dtF->diff($dtT)->format('%s') !=0 ){
$seconds = ($dtF->diff($dtT)->format('%s') == 1 ? ' %s Second' : ' %s Seconds');
}
else{
$seconds = '';
}
return $dtF->diff($dtT)->format($days.' '.$hours.' '.$min.' '.$seconds.'');
}
echo minutesToTime(456543.5);
OUTPUT
1317 Days, 1 Hour, 3 Minutes and 30 Seconds
There is a much simpler way of doing this without so many if statements but also providing the correct plural language.
echo minutes2human(1211);
function minutes2human($mins) {
$m = floor($mins % 60);
$h = floor(($mins % 1440) / 60);
$d = floor($mins / 1440);
$m_word = ($m == 1 ? 'Minute' : 'Minutes');
$h_word = ($h == 1 ? 'Hour' : 'Hours');
$d_word = ($d == 1 ? 'Day' : 'Days');
return "$d $d_word $h $h_word and $m $m_word";
}
We reduce a lot of your if statements by checking if minutes are 1, hours are 1, and if days are 1, then just combining them all into one string. As opposed to checking each possible case (if minutes are 1 and hours are not 1 and days are not 1, if minutes are 1, hours are 1, and days are not 1) etc...
Your problem is that you are setting the type for the variables before than the variables have value.
For the $hours, set the type after the division. Replace the line
$hours = $otime / 60;
for:
$hours = $otime / 60;
settype($hours, "integer");
It's probably that you will need to do this with the other variables $mins and $hour
I want to do what StackOverflow is doing which is saying exactly how long it's been since the last post. There is a catch though, SO displays certain information based on how long the ago the last post was - for example, if the post was less than a day ago, they post how many hours ago the last post was; if the post was less than an hour ago they post how many minutes ago it was, etc.
I'm working with a MYSQL DateTime field in the following format:
2012-09-19 13:28:45
I want to compare the above to the time NOW and so I converted that time using PHP's strtotime function and tried comparing the two dates through a function I put together (below). Granted, this is probably the WORST possible way of doing this but after reading about PHP's Date and DateTime functions I'm starting to become very, very confused.
function get_date_format($strToTimeString){
$minute = 60;
$hour = $minutes * 60;
$day = $hour * 24;
$week = $day * 7;
$month = $week * 4;
$year = $month * 12;
$timeNow = strtotime("now");
$timeDiff = $timeNow - $strToTimeString;
if($timeDiff > $minute){
if($timeDiff > $hour){
if($timeDiff > $day){
if($timeDiff > $week){
if($timeDiff > $month){
if($timeDiff > $year){
// Years ago
}
else{
// Months ago
}
}
else{
// Weeks ago
}
}
else{
// Days ago
}
}
else
{
// Hours ago
}
}
else{
// Minutes ago
}
}
else{
// Seconds ago
}
}
Is there a better way to do this? As I mentioned above, I had no luck when trying to use DateTime->diff
I really appreciate any help.
Use DateTime. Here's sample:
$now = new DateTime('now');
$posted = new DateTime($postDateFromDBHere);
$interval = $posted->diff($now);
var_dump($interval);
echo $interval->format('%y-%m-%d %h:%m:%s'); //You can do similar to format your output as you wish.
Use DateTime and DateTime:diff then check each value:
function returnInterval($date){
$datetime1 = new DateTime($date);
$datetime2 = new DateTime();
$diff = $datetime1->diff($datetime2);
$string = '';
$pass = '';
if($diff->y){
$string .= ($diff->y == 1) ? $diff->y." year" : $diff->y." years";
$pass = ', ';
}
if($diff->m){
$string .= $pass;
$string .= ($diff->m == 1) ? $diff->m." month" : $diff->m." months";
$pass = ', ';
}
if($diff->d){
$string .= $pass;
$string .= ($diff->d == 1) ? $diff->d." day" : $diff->d." days";
$pass = ', ';
}
if($diff->h){
$string .= $pass;
$string .= ($diff->h == 1) ? $diff->h." hour" : $diff->h." hours";
$pass = ', ';
}
if($diff->i){
$string .= $pass;
$string .= ($diff->i == 1) ? $diff->i." minute" : $diff->i." minutes";
$pass = ', ';
}
if($diff->s){
$string .= $pass;
$string .= ($diff->s == 1) ? $diff->s." second" : $diff->s." seconds";
}
$pos = strrpos($string, ',');
$string = substr_replace($string, ' and ', $pos, 2);
return $string;
}
echo returnInterval('2012-09-19 13:28:45');
// 8 days, 13 hours, 47 minutes and 44 seconds
After long searching, I got something close to what rottentomatoes used on their forum:
function realTimeSince($time){
define(MINUTE, 60);
define(HOUR, 60*60);
define(DAY, 60*60*24);
define(MONTH, 60*60*24*30);
$delta = strtotime(gmdate("Y-m-d H:i:s", time())) - strtotime($time);
if ($delta < 1 * MINUTE) {
return $delta == 1 ? "one second ago" : $delta . " seconds ago";
}
if ($delta < 2 * MINUTE) {
return "a minute ago";
}
if ($delta < 45 * MINUTE) {
return floor($delta / MINUTE) . " minutes ago";
}
if ($delta < 90 * MINUTE) {
return "an hour ago";
}
if ($delta < 24 * HOUR) {
return floor($delta / HOUR) . " hours ago";
}
if ($delta < 48 * HOUR) {
return "yesterday";
}
if ($delta < 30 * DAY) {
return floor($delta / DAY) . " days ago";
}
if ($delta < 12 * MONTH) {
$months = floor($delta / DAY / 30);
return $months <= 1 ? "one month ago" : $months . " months ago";
} else {
$years = floor($delta / DAY / 365);
return $years <= 1 ? "one year ago" : $years . " years ago";
}
}
so you can use it like this:
realTimeSince('2012-11-12 00:09:54'); //which can be got from a MySQL TIMESTAMP field
modified a little based on http://www.ferdychristant.com/blog//archive/DOMM-7QEFK4
Try the following function
function time_ago($date)
{
//echo "ss";
if (empty($date)) {
return "No date provided";
}
$periods = array("sec", "min", "hr", "day", "week", "month", "year", "decade");
$lengths = array("60","60","24","7","4.35","12","10");
$now = time();
$unix_date = strtotime($date);
// check validity of date
if (empty($unix_date)) {
return "Bad date";
}
// is it future date or past date
if ($now >= $unix_date) {
$difference= $now - $unix_date;
$tense = "ago";
} else {
$difference = $unix_date - $now;
$tense = "from now";
}
for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
$difference /= $lengths[$j];
}
$difference = round($difference);
if ($difference != 1 && $j != 0) {
$periods[$j].= "s";
}
if($difference!=0)
return "$difference $periods[$j] {$tense}";
else
return "a few seconds ago";
}
or
function time_elapsed_since ($postedDateTime){
$time = time() - $postedDateTime; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
time_elapsed_since($postedDateTime).' ago';
I use Codeigniter and it has the timespan() function that returns the time as 1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes.
What I'd like to do is only show the time formatted in x hours ago if the time is within the last 24 hours, otherwise just show a normal datetime.
I feel like there's got to be a function already made to do this but I haven't had any luck finding it.
This is the timespan function included with Codeigniter, how can I alter it?
/**
* Timespan
*
* Returns a span of seconds in this format:
* 10 days 14 hours 36 minutes 47 seconds
*
* #access public
* #param integer a number of seconds
* #param integer Unix timestamp
* #return integer
*/
if ( ! function_exists('timespan'))
{
function timespan($seconds = 1, $time = '')
{
$CI =& get_instance();
$CI->lang->load('date');
if ( ! is_numeric($seconds))
{
$seconds = 1;
}
if ( ! is_numeric($time))
{
$time = time();
}
if ($time <= $seconds)
{
$seconds = 1;
}
else
{
$seconds = $time - $seconds;
}
$str = '';
$years = floor($seconds / 31536000);
if ($years > 0)
{
$str .= $years.' '.$CI->lang->line((($years > 1) ? 'date_years' : 'date_year')).', ';
}
$seconds -= $years * 31536000;
$months = floor($seconds / 2628000);
if ($years > 0 OR $months > 0)
{
if ($months > 0)
{
$str .= $months.' '.$CI->lang->line((($months > 1) ? 'date_months' : 'date_month')).', ';
}
$seconds -= $months * 2628000;
}
$weeks = floor($seconds / 604800);
if ($years > 0 OR $months > 0 OR $weeks > 0)
{
if ($weeks > 0)
{
$str .= $weeks.' '.$CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')).', ';
}
$seconds -= $weeks * 604800;
}
$days = floor($seconds / 86400);
if ($months > 0 OR $weeks > 0 OR $days > 0)
{
if ($days > 0)
{
$str .= $days.' '.$CI->lang->line((($days > 1) ? 'date_days' : 'date_day')).', ';
}
$seconds -= $days * 86400;
}
$hours = floor($seconds / 3600);
if ($days > 0 OR $hours > 0)
{
if ($hours > 0)
{
$str .= $hours.' '.$CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')).', ';
}
$seconds -= $hours * 3600;
}
$minutes = floor($seconds / 60);
if ($days > 0 OR $hours > 0 OR $minutes > 0)
{
if ($minutes > 0)
{
$str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', ';
}
$seconds -= $minutes * 60;
}
if ($str == '')
{
$str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', ';
}
return substr(trim($str), 0, -1);
}
}
This function will accept a string, a numeric (unix) timestamp, or a DateTime object. It also accepts jQuery.now(). Time may be in the future or past.
function time_ago($time=false, $just_now=false) {
if ($time instanceOf DateTime)
$time = $time->getTimestamp();
elseif (is_numeric($time))
$time = date('m/d/y h:i A', $time);
if (strtotime($time) === false)
$time = date('m/d/y h:i A', time());
$interval = date_create($time)->diff(date_create('now'));
$adjective = strtotime($time) > time() ? 'from now' : 'ago';
return (
$interval->days > 0 ?
$time : (
$interval->h < 1 && $interval->i < 1 && $just_now ?
'just now' :
(
$interval->h > 1 ?
$interval->h.' hour'.(
$interval->h > 1 ?
's' :
''
).' ago' :
$interval->i.' minutes'.' '.$adjective
)
)
);
}
echo time_ago('8/22/2012 5:00 PM'); // 3 hours ago
echo time_ago('8/21/2012 5:00 PM'); // 8/21/2012 5:00 PM
echo time_ago(time()); // 0 hours ago
echo time_ago(time(), true); // just now
echo time_ago(strtotime('5 days ago')); // 08/17/12 08:18 PM
echo time_ago(strtotime('5 hours ago')); // 5 hours ago
echo time_ago(strtotime('5 minutes ago')); // 5 minutes ago
echo time_ago(strtotime('+5 minutes')); // 5 minutes from now
echo time_ago('jQuery.now()', true); // just now
echo time_ago('sweet explosions, bro!', true); // just now
Documentation
date - http://php.net/manual/en/function.date.php
DateTime object - http://www.php.net/manual/en/book.datetime.php
DateInterval object - http://www.php.net/manual/en/class.dateinterval.php
is_numeric - http://php.net/manual/en/function.is-numeric.php
if( time() - $yourTime <= 86400 ) { // 86400 seconds in a day
echo timespan($yourTime);
} else {
echo date('m/d/Y \a\t H:i:s', $yourTime);
}
Don't rely on a framework, especially a bad one, for everything!
Fiddle with $format to suit your needs. Will accept almost anything as input.
<?php
/**
* RelativeTime - pretty printed
* #author Dejan Marjanovic
*/
class Site5_RelativeTime
{
private $interval = '';
public function __construct()
{
call_user_func_array(array($this, 'calculate'), func_get_args());
}
public function calculate($start, $end = NULL)
{
if ( empty($start))
return false;
if (empty($end))
$end = time();
if ( ! is_numeric($start))
$start = strtotime($start);
if ( ! is_numeric($end))
$end = strtotime($end);
if($start > $end)
$future = TRUE;
$start = '#' . $start;
$end = '#' . $end;
if ( ! ($start instanceof DateTime))
$start = new DateTime($start);
if ($end === null)
$end = new DateTime();
if ( ! ($end instanceof DateTime))
$end = new DateTime($end);
$interval = $end->diff($start);
$get_plural = function($int, $str)
{
return $int > 1? $str.'s': $str;
};
$format = array();
if ($interval->y !== 0)
$format[] = "%y " . $get_plural($interval->y, "year");
if ($interval->m !== 0)
$format[] = "%m " . $get_plural($interval->m, "month");
if ($interval->d !== 0)
$format[] = "%d " . $get_plural($interval->d, "day");
if ($interval->h !== 0)
$format[] = "%h " . $get_plural($interval->h, "hour");
if ($interval->i !== 0)
$format[] = "%i " . $get_plural($interval->i, "minute");
if ($interval->s !== 0)
{
if ( ! count($format))
{
$this->interval = "less than a minute";
return;
}
else
{
$format[] = "%s " . $get_plural($interval->s, "second");
}
}
if (count($format) > 1)
{
$format = array_shift($format) . " and " . array_shift($format);
}
else
{
$format = array_pop($format);
}
$tense = ($future === TRUE)? 'from now': 'ago';
$this->interval = $interval->format($format) . ' ' . $tense;
}
public function __toString()
{
return $this->interval;
}
}
How could set a date and get a countdown in PHP? For example if I set the date as 3 December 2PM it would tell me how many days and hours are remaining.
No need for user inputs for the date as it will be hard coded.
Thanks.
You can use the strtotime function to get the time of the date specified, then use time to get the difference.
$date = strtotime("December 3, 2009 2:00 PM");
$remaining = $date - time();
$remaining will be the number of seconds remaining. Then you can divide that number to get the number of days, hours, minutes, etc.
$days_remaining = floor($remaining / 86400);
$hours_remaining = floor(($remaining % 86400) / 3600);
echo "There are $days_remaining days and $hours_remaining hours left";
Let me play around like this:
$rem = strtotime('2012-08-01 14:00:00') - time();
$day = floor($rem / 86400);
$hr = floor(($rem % 86400) / 3600);
$min = floor(($rem % 3600) / 60);
$sec = ($rem % 60);
if($day) echo "$day Days ";
if($hr) echo "$hr Hours ";
if($min) echo "$min Minutes ";
if($sec) echo "$sec Seconds ";
echo "Remaining...";
Try this at your leisure... :-)
NOTE: There is no if() test for echo "Remaining...", just coz you wont process this in case when $rem <= 0. Isn't it?
PHP 5.3 allows this:
$dt_end = new DateTime('December 3, 2009 2:00 PM');
$remain = $dt_end->diff(new DateTime());
echo $remain->d . ' days and ' . $remain->h . ' hours';
It's not as trivial as subtracting strtotime() results, since there are daylight savings and time would be mathematically correct, but not physically. Anyway, for these purposes you should use gmdate() function, which has no daylight savings:
$date = gmdate('U', strtotime('2009-12-03 14:00'));
// Get difference between both dates without DST
$diff = $date - gmdate('U');
// Days (in last day it will be zero)
$diff_days = floor($remaining / (24 * 60 * 60));
// Hours (in the last hour will be zero)
$diff_hours = floor($remaining % (24 * 60 * 60) / 3600);
Using #Izhar Aazmi solution, you could set this up nicely for display, as such:
public function countdown($time, $h = true, $m = true, $s = true) {
$rem = $time - time();
$day = floor($rem / 86400);
$hr = floor(($rem % 86400) / 3600);
$min = floor(($rem % 3600) / 60);
$sec = ($rem % 60);
if ( $day && !$h ) {
if ( $hr > 12 ) $day++; // round up if not displaying hours
}
$ret = Array();
if ( $day && $h ) $ret[] = ($day ? $day ." day".($day==1?"":"s") : "");
if ( $day && !$h ) $ret[] = ($day ? $day . " day" . ($day == 1 ? "" : "s") : "");
if ( $hr && $h ) $ret[] = ($hr ? $hr ." hour" . ($hr==1?"":"s") : "");
if ( $min && $m && $h ) $ret[] = ($min ? $min ." minute". ($min==1?"":"s") : "");
if ( $sec && $s && $m && $h ) $ret[] = ($sec ? $sec ." second".($sec==1?"":"s") : "");
$last = end($ret);
array_pop($ret);
$string = join(", ", $ret)." and {$last}";
return $string;
}
I hope this helps! It's a nice clean way or displaying the countdown.
Did this countdown until the end of the semester:
$endOfSemester = mktime(15,30,0,5,21,2015);
$now = time();
$secondsRemaining = $endOfSemester - $now;
define('SECONDS_PER_MINUTE', 60);
define('SECONDS_PER_HOUR', 3600);
define('SECONDS_PER_DAY', 86400);
$daysRemaining = floor($secondsRemaining / SECONDS_PER_DAY); //days until end
$secondsRemaining -= ($daysRemaining * SECONDS_PER_DAY); //update variable
$hoursRemaining = floor($secondsRemaining / SECONDS_PER_HOUR); //hours until end
$secondsRemaining -= ($hoursRemaining * SECONDS_PER_HOUR); //update variable
$minutesRemaining = floor($secondsRemaining / SECONDS_PER_MINUTE); //minutes until end
$secondsRemaining -= ($minutesRemaining * SECONDS_PER_MINUTE); //update variable
echo("<h3>There are $daysRemaining days, $hoursRemaining hours, $minutesRemaining minutes, $secondsRemaining seconds until the end of the semester</h3>"); //print message
For those looking for a function capable of handling larger and smaller time span (php >5.3) :
/**
* Return a textual representation of the time left until specified date
*/
function timeleft(DateTime $date){
$now = new DateTime();
if($now > $date){
return '0 second';
}
$interval = $date->diff($now);
if($interval->y){
return $interval->format("%y year").($interval->y > 1 ? 's':'');
} else if($interval->m){
return $interval->format("%m month").($interval->m > 1 ? 's':'');
} else if($interval->d){
return $interval->format("%d day").($interval->d > 1 ? 's':'');
} else if($interval->h){
return $interval->format("%h hour").($interval->h > 1 ? 's':'');
} else if($interval->i){
return $interval->format("%i minute").($interval->i > 1 ? 's':'');
} else if($interval->s) {
return $interval->format("%s second").($interval->s > 1 ? 's':'');
} else {
return 'milliseconds';
}
}