I have a MySql datetime value like "2012-04-17 20:48:29". I want to convert this to a simple text like "10 days ago". I want to do this in either php or javascript! I tried to create my own algorithm to do this. But is there an already available solution for doing this?
you could use this pattern
$date = "2012-04-17 20:48:29";
$seconds = time() - strtotime($date);
$days = floor($seconds / 86400);
$seconds -= $days * 86400;
$hours = floor($seconds / 3600);
$seconds -= $hours * 3600;
$minutes = floor($seconds / 60);
$seconds -= $minutes * 60;
echo "$days days, $hours hours, $minutes minutes, $seconds seconds ago";
you should of course add some conditions before echoing the result. to only show 1 minute ago, or 3 hours ago, or 10 days ago...
With this function you'll get outputs like:
1 minute
5 minutes
15 hours
4 days
2 months
1.5 years
function time_ago_in_words($time) {
$from_time = strtotime($time);
$to_time = strtotime(gmd());
$distance_in_minutes = round((($to_time - $from_time))/60);
if ($distance_in_minutes < 0)
return (string)$distance_in_minutes.'E';
if (between($distance_in_minutes, 0, 1))
return '1 minute';
elseif (between($distance_in_minutes, 2, 44))
return $distance_in_minutes.' minutes';
elseif (between($distance_in_minutes, 45, 89))
return '1 hour';
elseif (between($distance_in_minutes, 90, 1439))
return round($distance_in_minutes/60).' hours';
elseif (between($distance_in_minutes, 1440, 2879))
return '1 day';
elseif (between($distance_in_minutes, 2880, 43199))
return round($distance_in_minutes/1440).' days';
elseif (between($distance_in_minutes, 43200, 86399))
return '1 month';
elseif (between($distance_in_minutes, 86400, 525959))
return round($distance_in_minutes/43200).' months';
elseif ($distance_in_minutes > 525959)
return number_format(round(($distance_in_minutes/525960), 1), 1).' years';
}
So you could do:
// Last time you logged in: 15 days ago.
Last time you logged in: <?php echo time_ago_in_words($user['last_logged_in']) ?> ago.
// We haven't seen you for 15 days!
We haven't seen you for <?php echo time_ago_in_words($user['last_logged_in']) ?>!
With PHP, you can call strftime to get different out put. Look here for more details.
There is also a jQuery plugin that you might look at as well: jQuery-dateFormat
Have fun!
I use this function:
function duration($integer)
{
$seconds=$integer;
$minutes = 0;
$hours = 0;
$days = 0;
$weeks = 0;
$return = "";
if ($seconds/60 >=1)
{
$minutes=floor($seconds/60);
if ($minutes/60 >= 1)
{ # Hours
$hours=floor($minutes/60);
if ($hours/24 >= 1)
{ #days
$days=floor($hours/24);
if ($days/7 >=1)
{ #weeks
$weeks=floor($days/7);
if ($weeks>=2) $return="$weeks Weeks";
else $return="$weeks Week";
} #end of weeks
$days=$days-(floor($days/7))*7;
if ($weeks>=1 && $days >=1) $return="$return, ";
if ($days >=2) $return="$return $days days";
if ($days ==1) $return="$return $days day";
} #end of days
$hours=$hours-(floor($hours/24))*24;
if ($days>=1 && $hours >=1) $return="$return, ";
if ($hours >=2) $return="$return $hours hours";
if ($hours ==1) $return="$return $hours hour";
} #end of Hours
$minutes=$minutes-(floor($minutes/60))*60;
if ($hours>=1 && $minutes >=1) $return="$return, ";
if ($minutes >=2) $return="$return $minutes minutes";
if ($minutes ==1) $return="$return $minutes minute";
} #end of minutes
$seconds=$integer-(floor($integer/60))*60;
if ($minutes>=1 && $seconds >=1) $return="$return, ";
if ($seconds >=2) $return="$return $seconds seconds";
if ($seconds ==1) $return="$return $seconds second";
$return="$return.";
return $return;
}
echo duration(time() - strtotime($date));
Related
I am fetching time from server like this: 25-07-2015 12:25:28
Now I want to show it like this:
a few second ago
1 minute ago
30 minutes ago
1 Hour ago
12 Hours ago
and after 24 Hours ago
show me the date of that day like :
25 August 2015
the following code works. But no data validation done (eg: old>new)
<?php
$olddate = "25-08-2015 15:35:28"; //date as string
$now = time(); //pick present time from server
$old = strtotime( $olddate); //create integer value of old time
$diff = $now-$old; //calculate difference
$old = new DateTime($olddate);
$old = $old->format('Y M d'); //format date to "2015 Aug 2015" format
if ($diff /60 <1) //check the difference and do echo as required
{
echo intval($diff%60)."seconds ago";
}
else if (intval($diff/60) == 1)
{
echo " 1 minute ago";
}
else if ($diff / 60 < 60)
{
echo intval($diff/60)."minutes ago";
}
else if (intval($diff / 3600) == 1)
{
echo "1 hour ago";
}
else if ($diff / 3600 <24)
{
echo intval($diff/3600) . " hours ago";
}
else if ($diff/86400 < 30)
{
echo intval($diff/86400) . " days ago";
}
else
{
echo $old; ////format date to "2015 Aug 2015" format
}
?>
Change the looping if you can. Logic remains same.
<?php
function timeago($timestamp){
$time_ago = strtotime($timestamp);
$current_time = time();
$time_difference = $current_time - $time_ago;
$seconds = $time_difference;
$minutes = round($seconds / 60); // value 60 is seconds
$hours = round($seconds / 3600); //value 3600 is 60 minutes * 60 sec
$days = round($seconds / 86400); //86400 = 24 * 60 * 60;
$weeks = round($seconds / 604800); // 7*24*60*60;
$months = round($seconds / 2629440); //((365+365+365+365+366)/5/12)*24*60*60
$years = round($seconds / 31553280); //(365+365+365+365+366)/5 * 24 * 60 * 60
if ($seconds <= 60){
return "Just Now";
} else if ($minutes <= 60){
if ($minutes == 1){
return "one minute ago";
} else {
return "$minutes minutes ago";
}
} else if ($hours <= 24){
if ($hours == 1){
return "an hour ago";
} else {
return "$hours hrs ago";
}
} else if ($days <= 7){
if ($days == 1){
return "yesterday";
} else {
return "$days days ago";
}
} else if ($weeks <= 4.3){
if ($weeks == 1){
return "a week ago";
} else {
return "$weeks weeks ago";
}
} else if ($months <= 12){
if ($months == 1){
return "a month ago";
} else {
return "$months months ago";
}
} else {
if ($years == 1){
return "one year ago";
} else {
return "$years years ago";
}
}
}
?>
Have you looked at the Date function in php?
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';
Sorry for the slightly misleading title, I'm not really sure how to word this.
Basically, I'm working on a time clock-in system.
I've got the data for each clock in: clock in timestamp and clock out timestamp.
After all of the clockins have been displayed in a specific period, the script adds up all of the differences between the two timestamps.
The one thing I need to do now, is actually convert this figure into hours and minutes.
Use this function from more detailed output
function datefor($date, $time)
{
$days = floor($time / (60 * 60 * 24));
$remainder = $time % (60 * 60 * 24);
$hours = floor($remainder / (60 * 60));
$remainder = $remainder % (60 * 60);
$minutes = floor($remainder / 60);
$seconds = $remainder % 60;
if($days > 0) {
$data = date('F d Y', $date);
reset($date);
}
elseif($days == 0 && $hours == 0 && $minutes == 0) {
$data = "few seconds ago";
}
elseif($days == 0 && $hours == 0) {
$data = $minutes.' minutes ago';
}
elseif($days == 0 && $hours > 0) {
$data = $hours.' hour ago';
}
else {
$data = "few seconds ago";
}
return $data;
}
and select using the following statement
SELECT *,UNIX_TIMESTAMP() - datetime AS TimeSpent FROM `table_name`;
$result=mysql_query($sql);
while($rows=mysql_fetch_array($result)){
//call function
$check = datefor($rows['datetime'], $rows['TimeSpent']);}
now echo $check; where you want the time to be displayed.
<strong>So far, you have worked <?php
$hours = floor($i / 3600);
$i -= 3600 * floor($i / 3600);
$minutes = floor($i / 60);
echo $hours; ?> hours and <?php echo $minutes; ?> minutes</strong>
yep, it works.
If my code looks like:
if($seconds < 60)
$interval = "$seconds seconds ago";
else
if($seconds < 3600)
$interval = floor($seconds / 60) . "minutes ago";
else
if($seconds < 86400)
$interval = floor($seconds / 3600) . "hours ago";
else
$interval = floor($seconds / 86400) . "days ago";
How would I get rid of it saying stuff like:
1 Days ago.
1 Years ago.
1 Minutes ago.
1 Hours ago.
Thanks :)
If your app is international and using the gettext extension, you can do something like this:
sprintf(ngettext('%d minute', '%d minutes', $amount), $amount);
You can create a wrapper function to it:
function pluralize($singular, $plural, $num) {
return sprintf(ngettext($singular, $plural, $num), $num);
}
This is the best way imo.
Can be done quite concisely with a ternary operator:
if($seconds < 60) {
$interval = "$seconds second" . (($seconds != 1) ? "s" : "") . " ago";
} else {
if($seconds < 3600) {
$minutes = floor($seconds / 60);
$interval = "$minutes minute" . (($minutes > 1) ? "s" : "") . " ago";
} else {
if($seconds < 86400) {
$hours = floor($seconds / 3600);
$interval = "$hours hour" . (($hours > 1) ? "s" : "") . " ago";
} else {
$days = floor($seconds / 86400);
$interval = "$days day" . (($days > 1) ? "s" : "") . " ago";
}
}
}
Yet another solution.
if($seconds < 60)
$interval = "$seconds second";
else
if($seconds < 3600)
$interval = floor($seconds / 60) . " minute";
else
if($seconds < 86400)
$interval = floor($seconds / 3600) . " hour";
else
$interval = floor($seconds / 86400) . " day";
$interval .= (reset(explode(" ", $interval)) != 1 ? "s" : "")." ago";
$time = "120";
$array = array("second" => 1,
"minute" => 60,
"hour" => 60,
"day" => 24,
"year" => 365);
$old_time = 0;
$old_type = false;
// Loop through each type
foreach($array as $type => $seconds)
{
// Divide
$time = floor($time/$seconds);
// If it went into a value lower than 0, stop dividing
if($time < 1)
{
$time = $old_time;
$type = $old_type;
break;
}
else
{
// Continue dividing.
$old_time = $time;
$old_type = $type;
}
}
if($time == 1)
{
$interval = $time . " ". $type . " ago";
}
else
{
$interval = $time ." " . $type . "s ago";
}
echo $interval;
This divides through all the possible time types, and gives one that doesn't turn it into a fraction. By separating the number value from the type, we are then able to test if the number is == 1, and correct the word.
if ($interval < 60) {
$unit = 'Second';
} else if ($interval < 1440) {
$unit = 'Minute'; $interval /= 60;
} else if ($interval < 86400) {
$unit = 'Hour'; $interval /= 1440;
} else {
$unit = 'Day'; $interval /= 86400;
}
$interval = intval($interval);
$interval = "$interval $unit" . ($interval == 1 ? '' : 's') . " ago";
Here is a generic PHP snip for getting strings like "1 month, 2 weeks and 30 seconds ago".
$timeUnits = array("month" => 2592000,
"week" => 604800,
"day" => 86400,
"hour" => 3600,
"minute" => 60,
"second" => 1);
$tmpSeconds = $seconds;
$timeAgoStrings = array();
foreach ($timeUnits as $name => $numOfSeconds) {
if ($seconds > $numOfSeconds) {
$val = floor($tmpSeconds / $numOfSeconds);
$agoStr = ($val > 1) ? $name."s" : $name;
$timeAgoStrings[] = "$val $agoStr";
$tmpSeconds = $tmpSeconds - $val; // cut the used time units off our tmpSeconds variable
}
}
//check if we have more than one string - in case we do then we will pop the last val and add an "and" prefix before the last val instead of a comma
if (count($timeAgoStrings) > 1) {
$lastString = array_pop($timeAgoStrings);
$timeAgoStr = implode(", ",$timeAgoStrings)." and $lastString ago";
} else {
$timeAgoStr = $timeAgoStrings[0]." ago";
}
Do the math.
else if($seconds < 120)
$interval = "1 minute ago";
else if($seconds < 172800)
$interval = "1 day ago"
etc.
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';
}
}