This question already has answers here:
Calculate relative time in C#
(41 answers)
How to display "12 minutes ago" etc in a PHP webpage? [closed]
(3 answers)
Closed 8 years ago.
So my current $item['date'] function gets the time and date of the post in this format Y-m-d H:i:s.
I want to display how many minutes was the post posted or if it is more than 24 hours, how many days ago was it posted OR like 0 days and 20 hours ago? something like that
Why doesn't the minus operator work here my code?
My current code:
<p><?php echo date('Y-m-d H:i:s') - $item['date'] ?> minutes ago</p>
I usually use this function. Use it like this time_ago('2014-12-03 16:25:26')
function time_ago($date){
$retval = NULL;
$granularity=2;
$date = strtotime($date);
$difference = time() - $date;
$periods = array('decade' => 315360000,
'year' => 31536000,
'month' => 2628000,
'week' => 604800,
'day' => 86400,
'hour' => 3600,
'minute' => 60,
'second' => 1);
foreach ($periods as $key => $value)
{
if ($difference >= $value)
{
$time = round($difference/$value);
$difference %= $value;
$retval .= ($retval ? ' ' : '').$time.' ';
$retval .= (($time > 1) ? $key.'s' : $key);
$granularity--;
}
if ($granularity == '0') { break; }
}
return $retval.' ago';
}
What you need to do is convert both dates to timestamp first and substract your original post date from current date and reconvert it back to your desired format. As an example see below.
$now = time();
$datePosted = strtotime($item['date']);
$timePassed = $now - $datePosted;
$agoMinutes = $timePassed/60; //this will give you how many minutes passed
$agoHours = $agoMinutes/60; //this will give you how many hours passed
$agoDays = $agoHours/24; // this will give you how many days passed
And so on ...
Php's timestamp gives date in seconds so it is easier to calculate and work on it if you need mathematical operations.
Related
I have a function like this:
function time_elapsed_string($ptime)
{
$date_time = strtotime("1348-10-10 04:30:01") + $ptime;
$year = date("Y",$date_time);
$month = date("m",$date_time);
$day = date("d",$date_time);
$time = date("H:i:s",$date_time);
$etime = time() - $ptime + 1;
$a = array( 31536000 => 'year',
2592000 => 'month',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($a as $secs => $str)
{
$d = $etime / $secs;
if ($d >= 1)
{
$r = round($d);
// EX:
return array('date' => $day.'-'.$month.'-'.$year, // 2016-02-20
'time' => $time, // 03:30:04
'difference' => $r . ' ' . $str . ' ago' // 2 month ago
);
}
}
}
And I use it like this:
$ptime = 1470692661;
$html = '<span title="date: '.time_elapsed_string($ptime)['date'].' time: '.time_elapsed_string($ptime)['time'].'">in '.time_elapsed_string($ptime)['difference'].'<span>';
As you see, I'm using of that function's result like this:
time_elapsed_string($ptime)['date']
ime_elapsed_string($ptime)['time']
time_elapsed_string($ptime)['difference']
In fact I'm calling that function every time I need one of its results. Is that right? Or should I call it once and store it into an array?
Note: My code works as well.
Counting time elapsed since some date/time like this is mauvais ton.
DateTime has been available since PHP 5.2.0 and tonns of people underestimate it. Why don't you use this instead of loops and ifs?
$create_time = "2016-08-02 12:35:04";
$current_time="2016-08-02 16:16:02";
$dtCurrent = DateTime::createFromFormat('Y-m-d H:i:s', $current_time);
// to use current timestamp, use the following:
//$dtCurrent = new DateTime();
$dtCreate = DateTime::createFromFormat('Y-m-d H:i:s', $create_time);
$diff = $dtCurrent->diff($dtCreate);
Now, you can format the result however you want:
$interval = $diff->format("%h hours %i minutes %s seconds");
This will give a clean 3 hours 40 minutes 58 seconds without any arrays, which is better.
UPDATE
There is a general solution to get hours / minutes / seconds via regex:
$interval = $diff->format("%y years %m months %d days %h hours %i minutes %s seconds");
// now remove zero values
$interval = preg_replace('/(^0| 0) (years|months|days|hours|minutes|seconds)/', '', $interval);
UPDATE 2
As of your comment:
Look, I want to use your approach .. but I really cannot implement it .. Actually I need three things: time, date, difference ..! But your approach doesn't give me them..
Well, we already know how to get the difference, it's the $interval variable described above.
To get time and date, you can get it from the $dtCreate variable by, again, using format:
$time = $dtCreate->format('H:i:s');
$date = $dtCreate->format('d-m-Y');
This is a no brainer.
Yes - store the function call result of time_elapsed_string($ptime) in an array, then use that to access your results. You're wasting CPU cycles otherwise!
// call it once
$result = time_elapsed_string($ptime);
// then use:
$result['date'];
$result['time'];
$result['difference'];
This question already has answers here:
Converting timestamp to time ago in PHP e.g 1 day ago, 2 days ago...
(32 answers)
Closed 8 years ago.
i have a span tag which has array data like
<?php echo " <span >".$comments_array[$j]['posted_time']."</span> "; ?>
and it echo's time of the comment as 2014-04-11 05:07:52
now i have a function that display the time in the format of x hrs ago,
below is the function
define("SECOND", 1);
define("MINUTE", 60 * SECOND);
define("HOUR", 60 * MINUTE);
define("DAY", 24 * HOUR);
define("MONTH", 30 * DAY);
function relTime($time)
{
$now = new DateTime;
$dateObj = new DateTime($dt);
$diff = (array) $now->diff($dateObj);
$diff['w'] = floor($diff['d'] / 7);
$diff['d'] -= $diff['w'] * 7;
$tokens = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second'
);
foreach ($tokens as $unit => &$text)
{
if ($diff[$unit])
{
$text = sprintf(
'%s %s%s',
$diff[$unit], $text, ($diff[$unit] > 1 ? 's' : '')
);
}
else
{
unset($tokens[$unit]);
}
}
return array_shift($tokens);
}
now how can i call that function and echo that time in desired format
help me please
There's a better and cleaner way to achieve this. Here's a function, which, given a date/time string and a format string, will return the difference from now in the desired format.
function getDatetimeDifference($datetime, $format) {
$datetime_obj = new DateTime($datetime);
$now = new DateTime();
$difference = date_diff($now, $datetime_obj);
$result = $difference->format($format);
return $result;
}
Here's a use case:
echo getDatetimeDifference(
'2013-04-11 10:35:33',
'%R%a days, %h hours, %i minutes, %s seconds ago'
);
// Outputs "-364 days, 23 hours, 55 minutes, 10 seconds ago"
If you want to work with the total amount of hours since that time, you will fare better if you work with timestamps, since you can easily substract the difference and then divide it by 3600 to get the time difference in hours.
Keep in mind that the DateTime objects will overflow if you don't pass the appropriate format - for example, if you use the above function to get only the hours between now and the last year, you will get 23 as result. My advice - use a similar function, pass a suitable format that you can parse later in tokens, and eliminate left to right tokens until you reach a non-negative value.
Cheers.
im trying to convert a mysql timestamp to time in months or days or hours or minutes.
so the output will look like this:
added 1 month ago / added: 0 hours ago / added: 21 minutes ago / added 30 seconds ago
so i only want one format of time depending on how many minutes or how many hours or how many days etc, so 60 minutes converts to 1 hour ago or 24 hours converts to 1 day ago and 48 hours converts to 2 dayS ago.
so far i have this code:
<?
$datetime1 = new DateTime();
$datetime2 = new DateTime ($news['date_added']);
$interval = $datetime1->diff($datetime2);
str_replace('0 hours', '', $variable);
echo $interval->format('%h hours %i minutes');
?>
and this outputs the following:
added 0 hours ago 57 minutes ago.
can someone help me or show me what id need to do in order to get the formats to display right, im really new to php and am not sure how i can do this. thank you.
From http://php.net/manual/en/ref.datetime.php
Just change $precision to 1 when you call the function and add in whatever text you want to come before and after the date. You'll have to make sure you convert your date objects to timestamps, but that shouldn't be a problem for you.
/**
* this code assumes php >= 5.1.0. if using < 5.1, read
* php.net/strtotime and change the condition for checking
* for failure from strtotime()
*/
// $t1, $t2: unix times, or strtotime parseable
// $precision: max number of units to output
// $abbr: if true, use "hr" instead of "hour", etc.
function date_diff ($t1, $t2, $precision = 6, $abbr = false) {
if (preg_match('/\D/', $t1) && ($t1 = strtotime($t1)) === false)
return false;
if (preg_match('/\D/', $t2) && ($t2 = strtotime($t2)) === false)
return false;
if ($t1 > $t2)
list($t1, $t2) = array($t2, $t1);
$diffs = array(
'year' => 0, 'month' => 0, 'day' => 0,
'hour' => 0, 'minute' => 0, 'second' => 0,
);
$abbrs = array(
'year' => 'yr', 'month' => 'mth', 'day' => 'day',
'hour' => 'hr', 'minute' => 'min', 'second' => 'sec'
);
foreach (array_keys($diffs) as $interval) {
while ($t2 >= ($t3 = strtotime("+1 ${interval}", $t1))) {
$t1 = $t3;
++$diffs[$interval];
}
}
$stack = array();
foreach ($diffs as $interval => $num)
$stack[] = array($num, ($abbr ? $abbrs[$interval] : $interval) . ($num != 1 ? 's' : ''));
$ret = array();
while (count($ret) < $precision && ($item = array_shift($stack)) !== null) {
if ($item[0] > 0)
$ret[] = "{$item[0]} {$item[1]}";
}
return implode(', ', $ret);
}
$t1 = 'Feb 4, 2008 12:16:00';
$t2 = 'Jul 3, 2006 16:15:30';
echo date_diff($t1, $t2), "\n",
date_diff($t1, $t2, 3), "\n",
date_diff($t1, $t2, 2, true), "\n";
?>
Here is a possible solution. You format the time difference as a string with months-days-hours-minutes-seconds, then look through that string for the first non-zero number: that's the one you want...
$mdhms = explode('-',$interval->format('%m-%d-%H-%i-%s'));
$labels = Array(' months', ' days', ' hours', ' minutes', ' seconds');
$i = 0;
foreach($mdhms as $t){
if($t > 0) break;
$i+=1;
}
if ($i < 5) echo "It happened ".$t.$labels[$i]." ago";
else echo "It is happening right now!"
I'm working with a function I found to do this, but I'm trying to make it work with a GMT utc timestamp:
EDIT:
Maybe my issue is with how i'm "converting" the user input time to GMT...
I was doing
$the_user_input_date = strtotime('2011-07-20T01:13:00');
$utctime = gmdate('Y-m-d H:i:s',$the_user_input_date);
Does gmdate('Y-m-d H:i:s',$the_user_input_date); not actually "convert" it to gmt? does it just format it? Maybe thats my issue.
Here's what the times I can supply would look like:
//local time in GMT
2011-07-20T01:13:00
//future time in GMT
2011-07-20T19:49:39
I'm trying to get this to work like:
Started 36 mins ago
Will start in 33 mins
Will start in 6 hrs 21 mins
Will start in 4 days 4 hrs 33 mins
Here's what im working with so far:
EDIT: new php code im working with, seems to ADD 10 HOURS on to my date. Any ideas? I updated it here:
function ago($from)
{
$to = time();
$to = (($to === null) ? (time()) : ($to));
$to = ((is_int($to)) ? ($to) : (strtotime($to)));
$from = ((is_int($from)) ? ($from) : (strtotime($from)));
$units = array
(
"year" => 29030400, // seconds in a year (12 months)
"month" => 2419200, // seconds in a month (4 weeks)
"week" => 604800, // seconds in a week (7 days)
"day" => 86400, // seconds in a day (24 hours)
"hour" => 3600, // seconds in an hour (60 minutes)
"minute" => 60, // seconds in a minute (60 seconds)
"second" => 1 // 1 second
);
$diff = abs($from - $to);
$suffix = (($from > $to) ? ("from now") : ("ago"));
foreach($units as $unit => $mult)
if($diff >= $mult)
{
$and = (($mult != 1) ? ("") : ("and "));
$output .= ", ".$and.intval($diff / $mult)." ".$unit.((intval($diff / $mult) == 1) ? ("") : ("s"));
$diff -= intval($diff / $mult) * $mult;
}
$output .= " ".$suffix;
$output = substr($output, strlen(", "));
return $output;
}
#Jason
I tried what you suggested here:
function ago($dateto)
{
$datetime1 = new DateTime( $dateto);
$datetime2 = new DateTime();
$interval = $datetime1->diff($datetime2);
// print_r($interval);
$format = '';
if ($interval->h) {
$format .= ' %h ' . ($interval->h == 1 ? 'hour' : 'hours');
}
if ($interval->i) {
$format .= ' %i ' . ($interval->i == 1 ? 'minute' : 'minutes');
}
// more logic for each interval
if ($format) {
echo $interval->format($format), ' ago';
}
else {
echo 'now';
}
}
It always seems to add 10 hours on to my time.
Any ideas what could be going on?
Maybe an error lies with how I'm saving the target time?
When someone submits a time its converted and stored like this
The user submitted time will always start out looking like this as their local time:
07/20/2011 11:00 pm
Then:
$time = mysql_real_escape_string($_POST['time']);
$the_date = strtotime($time);
//make user input time into GMT time
$utctime = gmdate('Y/m/d H:i:s',$the_date);
$query = "INSERT INTO $table (time) VALUES ('$utctime');";
mysql_query($query);
Provided you have access to PHP >= 5.3 I'd recommend DateTime::diff(). The DateInterval returned gives you all the parts you would need for display as well as has its own methods, such as format().
Here's a sample to give you an idea. There are more complete samples in the comments of the PHP documentation links.
<?php
$datetime1 = new DateTime('2011-07-20');
$datetime2 = new DateTime();
$interval = $datetime1->diff($datetime2);
// print_r($interval);
$format = '';
if ($interval->h) {
$format .= ' %h ' . ($interval->h == 1 ? 'hour' : 'hours');
}
if ($interval->i) {
$format .= ' %i ' . ($interval->i == 1 ? 'minute' : 'minutes');
}
// more logic for each interval
if ($format) {
echo $interval->format($format), ' ago';
}
else {
echo 'now';
}
It outputs (on my system):
22 hours 10 minutes ago
Your $datefrom is a string, but $dateto is an int. You can't subtract them that way.
Instead of:
$datefrom=gmdate("Y/m/d\TH:i:s\Z");
Do:
$datefrom=time();
PS. I did not check the rest of the code.
I'm trying to work with dates for the first time, I did it something about that with Flash but it's different.
I have two different dates and I'd like to see the difference in hours and days with them, I've found too many examples but not what I'm loking for:
<?php
$now_date = strtotime (date ('Y-m-d H:i:s')); // the current date
$key_date = strtotime (date ("2009-11-21 14:08:42"));
print date ($now_date - $key_date);
// it returns an integer like 5813, 5814, 5815, etc... (I presume they are seconds)
?>
How can I convert it to hours or to days?
The DateTime diff function returns a DateInterval object. This object consists of variabeles related to the difference. You can query the days, hours, minutes, seconds just like in the example above.
Example:
<?php
$dateObject = new DateTime(); // No arguments means 'now'
$otherDateObject = new DateTime('2008-08-14 03:14:15');
$diffObject = $dateObject->diff($otherDateObject));
echo "Days of difference: ". $diffObject->days;
?>
See the manual about DateTime.
Sadly, it's a PHP 5.3> only feature.
Well, you can always use date_diff, but that is only for PHP 5.3.0+
The alternative would be math.
How can I convert it [seconds] to hours or to days?
There are 60 seconds per minute, which means there are 3600 seconds per hour.
$hours = $seconds/3600;
And, of course, if you need days ...
$days = $hours/24;
If you dont have PHP5.3 you could use this method from userland (taken from WebDeveloper.com)
function date_time_diff($start, $end, $date_only = true) // $start and $end as timestamps
{
if ($start < $end) {
list($end, $start) = array($start, $end);
}
$result = array('years' => 0, 'months' => 0, 'days' => 0);
if (!$date_only) {
$result = array_merge($result, array('hours' => 0, 'minutes' => 0, 'seconds' => 0));
}
foreach ($result as $period => $value) {
while (($start = strtotime('-1 ' . $period, $start)) >= $end) {
$result[$period]++;
}
$start = strtotime('+1 ' . $period, $start);
}
return $result;
}
$date_1 = strtotime('2005-07-31');
$date_2 = time();
$diff = date_time_diff($date_1, $date_2);
foreach ($diff as $key => $val) {
echo $val . ' ' . $key . ' ';
}
// Displays:
// 3 years 4 months 11 days
TheGrandWazoo mentioned a method for php 5.3>. For lower versions you can devide the number of seconds between the two dates with the number of seconds in a day to find the number of days.
For days, you do:
$days = floor(($now_date - $key_date) / (60 * 60 * 24))
If you want to know how many hours are still left, you can use the modulo operator (%)
$hours = floor((($now_date - $key_date) % * (60 * 60 * 24)) / 60 * 60)
<?php
$now_date = strtotime (date ('Y-m-d H:i:s')); // the current date
$key_date = strtotime (date ("2009-11-21 14:08:42"));
$diff = $now_date - $key_date;
$days = floor($diff/(60*60*24));
$hours = floor(($diff-($days*60*60*24))/(60*60));
print $days." ".$hours." difference";
?>
I prefer to use epoch/unix time deltas. Time represented in seconds and as such you can very quickly divide by 3600 for hours and divide by 24*3600=86400 for days.