Print out Relative Date / Time from SQL / PHP Datestamp - php

I have a SQL Datestamp like this: 2012-02-20 21:14:54
How would I print out the relative date and time in PHP?
e.g.
Occured: a few seconds ago
Occured: 4 minutes ago
Occured: 4 hours ago
Occured: Monday Jan 8th, 2012
After the hours I just want to print out the actual date

Found this after two seconds of Google http://www.mdj.us/web-development/php-programming/another-variation-on-the-time-ago-php-function-use-mysqls-datetime-field-type
In general you chose a unit of time like seconds, test if the time-difference is smaller then the max-value for this unit (60s) and if so, print out "$timeDifference $unit". If not you divide the difference by the units max-value and start over with the next higher unit (minutes).
Example:
$timeDif = 60*60*5 + 45; // == 5 hours 45 seconds
// 60 seconds in a minute
if ($timeDif < 60) // false
return "$timeDif second(s) ago";
// convert seconds to minutes
$timeDif = floor($timeDif / 60); // == 300 = 5 * 60
// 60 minutes in an hour
if ($timeDif < 60) // false
return "$timeDif minute(s) ago";
// convert minutes to hours
$timeDif = floor($timeDif / 60); // == 5
// 24 hours in a day
if ($timeDif < 24)
return "$timeDif hour(s) ago";
// ...

Here's what a MySQL solution might look like:
SELECT date_field, IF (DATEDIFF( NOW(), date_field) < 1, IF ( TIMEDIFF( NOW(), date_field ) < '01:00:00', CONCAT(MINUTE(TIMEDIFF(NOW(), date_field)), ' minutes'), CONCAT(HOUR(TIMEDIFF(NOW(), date_field )), ' hours')), date_field) AS occurred
FROM table

That is no so hard to code. Moreover is quite fun make it. Here a sample, Just put hands to work.
Start converting SQL Datestamp to unixtime like this:
$unixtime = strtotime('2012-02-20 21:14:54');

Related

Time difference php/mysql need to format the output conditionally (4 small highlights required)

im trying to get difference of date/time from a field type datetime to "right now" using php and mysql as database
this code is working fine, returns the output beautifully ok as required
$datetime1 = new DateTime('mydate1');
$datetime2 = new DateTime();
$interval = $datetime1->diff($datetime2);
$elapsed = $interval->format('%d days %h hours %i minutes');
that is ok so far, no issues as this function is for php 5.3 and i have it on server
my need is 4 small things actually
1) how to eliminate the need for days?
i want to have (25 hours 10 minutes) instead of (1 day 1 hours 10 minutes)
2) how i can make $elapsed be bold or colored if the value is more than 5 hours for example!? simple IF logic will not work as the output is not actually a predefined value...
3) if the days or hours are 0, then want to remove them!
- For example if showing (0 days 10 hours 40 mins) then no need to display the (0 days), should show (10 hours 40 mins) that is enough
- Another example: 0 days 0 hours 45 minutes then to show only "45 minutes" no need for days and hours!
4) if output less than 5 minutes in total (0days 0 hours 1-5mins), then wanna make it show like "a while ago" only no need for any days, hours or minutes... then after 6 minutes.. go like "6 mins"
shortly something like facebook!?
okay, what i searched tried is different combination of workarounds but never worked as you know this interval is for php 5.3 and still seem not widely used?
any hint for one or more parts of this long question is appreciated,
M, Derik
tried to answer all your questions. so read the comments because i didnt write numbers for the problems. sorry
$datetime1 = new DateTime('mydate1');
$datetime2 = new DateTime();
$minutes = round(abs($datetime1 - $datetime2) / 60,2); //to calculate total time in MINUTES
if($minutes < 5) // for awhile ago problem.
{
return "awhile ago";
}
elseif($minutes > 6 && < 60)
{
return $minutes." minutes ago"; //for 6 minutes and after.
}
elseif($minutes>60) // for the hours..
{
$hours = floor($final_time_saving / 60);
$minutes = $final_time_saving % 60;
$string = $hours. " hours and" . $minutes . " minutes ago.";
if($hours>5) //for bolding characters after
{
return "<b>".$hours." hours and".$minutes." minutes ago.</b>"; //for bolding character
}
else
return $hours." hours and".$minutes." minutes ago.";
}
hope this helps.

PHP Checking if timestamp is less than 30 minutes old

I'm getting a list of items from my database, each has a CURRENT_TIMESTAMP which i have changed into 'x minutes ago' with the help of timeago. So that's working fine. But the problem is i also want a "NEW" banner on items which are less than 30 minutes old. How can i take the generated timestamp (for example: 2012-07-18 21:11:12) and say if it's less than 30 minutes from the current time, then echo the "NEW" banner on that item.
Use strtotime("-30 minutes") and then see if your row's timestamp is greater than that.
Example:
<?php
if(strtotime($mysql_timestamp) > strtotime("-30 minutes")) {
$this_is_new = true;
}
?>
I'm using strtotime() twice here to get unix timestamps for your mysql date, and then again to get what the timestamp was 30 minutes ago. If the timestamp from 30 mins ago is greater than the timestamp of the mysql record, then it must have been created more than 30 minutes go.
Try something like this, using PHP's DateTime object:
$now = new DateTime();
$then = DateTime($timestamp); // "2012-07-18 21:11:12" for example
$diff = $now->diff($then);
$minutes = ($diff->format('%a') * 1440) + // total days converted to minutes
($diff->format('%h') * 60) + // hours converted to minutes
$diff->format('%i'); // minutes
if ($minutes <= 30) {
echo "NEW";
}
Edit: Mike is right, I forgot that for whatever reason, only %a actually returns the total of its type (in this case days). All the others are for displaying time formatting. I've extended the above to actually work.
You can do like this also -
$currentTime=time();
to check the last updated time is 30 minute old or not
last_updated_at < $currentTime - (60*30)

Need to rewrite function for date display

I have the following function that I wrote couple of years ago. It takes a datetime from my db and displays it in a better formatted way.
function formatTime($dateTime){
// show time only if posted today
if (date('Ymd') == date('Ymd', strtotime($dateTime))) {
$dt = date('g:i a', strtotime($dateTime));
} else {
// if not the same year show YEAR
if (date('Y') == date('Y', strtotime($dateTime))) {
$dt = date('M j', strtotime($dateTime));
} else {
$dt = date('M j, Y', strtotime($dateTime));
}
}
return $dt;
}
I use server time, which is CST for me. Yesterday I had a user from Australia pointing out that for him it did not make any since since he way on an entirely different time zone, actually a day ahead (when compared to my output at certain time :).
I decided to rewrite my function to say something like:
if under a minute > seconds ago
if under an hour > # minutes ago
between 1 -2 hrs > over an hour ago
2 - 24 hrs > day ago
2 - 7 days > # days ago
7 days - month > # weeks ago
1 - 2 months > over a month
after that I can just show a date
Are there any functions that you are perhaps aware of doing this, if not how would I modify this one?
Thanks.
function formatTime ($dateTime) {
// A Unix timestamp will definitely be required
$dateTimeInt = strtotime($dateTime);
// First we need to get the number of seconds ago this was
$secondsAgo = time() - $dateTimeInt;
// Now we decide what to do with it
switch (TRUE) {
case $secondsAgo < 60: // Less than a minute
return "$secondsAgo seconds ago";
case $secondsAgo < 3600: // Less than an hour
return floor($secondsAgo / 60)." minutes ago";
case $secondsAgo < 7200: // Less than 2 hours
return "over an hour ago";
case $secondsAgo < 86400: // Less than 1 day
return "1 day ago"; // This makes no sense, but it is what you have asked for...
case $secondsAgo < (86400 * 7): // Less than 1 week
return floor($secondsAgo / 86400)." days ago";
case $secondsAgo < (86400 * 28): // Less than 1 month - for the sake of argument let's call a month 28 days
return floor($secondsAgo / (86400 * 7))." weeks ago";
case $secondsAgo < (86400 * 56): // Less than 2 months
return "over a month ago";
default:
return date('M j, Y', $dateTimeInt);
}
}
This is by no means flawless, especially since one of your requirements doesn't make sense (see comments) but hopefully it should give you a push in the right direction, and illustrate how you can use switch to allow you to easily add and remove items/options from the behaviour.

Changing hours to days

Editing the question.
I have SQL like this:
`table1`.`DateField` >= DATE_SUB(NOW(), INTERVAL {$days} DAY
Now 24 hours make a whole day. However, what if I want to do the query for the last 3 hours or so?
My table1.DateField is in the format of 2010-03-10 10:05:50.
Original post:
If I have this
1 hour
2 hours
3 hours
..
24 hours
How would I change it to days?
Thanks.
$hours = 80;
$hid = 24; // Hours in a day - could be 24, 8, etc
$days = round($hours/$hid);
if( $days < 0 )
{
echo "$hours hours";
}
else
{
echo "$days days";
}
This assumes you want the hours if it's less than 1 day. If not just remove the switch.
MySQL not only knows DAY as a unit for an interval but also HOUR, MINUTE, ....
see http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-add
$x = 32;
$sql = "SELECT
x,y,z
FROM
foo
WHERE
`table1`.`DateField` >= NOW() - INTERVAL $x HOUR
";
As simple as:
if you want to convert the total of those hour to day:
Just sum the total of hours and that total must be divided by 24
(1 + 2 + 3 + 5) / 24
If you want to convert all of those hours to days:
Just divide by 24 every hours in your list
(1/24) (2/24) (3/24) (5/24)

How can i display seconds ago/minutes ago/with unix timestamp?

I need the unix timestamp - the timestamp i have. Then display the time between like on twitter.
If you have the difference called diff:
$seconds = intval($diff) % 60;
$minutes = intval($diff/60) % 60;
$hours = intval($diff/3600) % 24;
$days = intval($diff/(3600*24));
Is this what you want ?
Not sure what language you need it, but if it will end up in a web page, you may try timeago.
Use example :
echo time_elapsed_string('#1367367755');
echo time_elapsed_string('#1367367755', true);
Output :
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
Link to the function.

Categories