I contacted the hosting team of my shared host at Godaddy to change the server time because I use different timezone (Cairo), but they couldn't change it on the shared hosting.
I hope you help me to modify the code I use to calculate the time since the user inserted the data to the Mysql database.
I use datetime for date fields.
Here is the code:
//This is the date the code inserts to the database:
$date = new DateTime("now", new DateTimeZone('Africa/Cairo'));
$date=$date->format("Y-m-d H:i:s");
//And this is the php function that calculates the time since post published:
function humanTiming($time)
{
$time = time() - $time; // 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)?'':'');
}
}
Instead of using your real timezone 'Africa/Cairo', you could use the timezone of the server (to match the database). Since you're looking for the time difference, it would be accurate.
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'];
Hello :) I have been trying to work on this piece of PHP script, to select all of the DateTime rows that meet certain criteria, then to calculate the time difference from then to current time.
My PHP script just echos "44 years ago." When I have more then one record in the database, and the echo is totally wrong, I do not have a record in the database that old.
I do know that I can echo the appropriate datetimes inside the selection loop, the select criteria does work.
Some help is appreciated. :)
My PHP code is below:
<?php
//AJAX REQUEST
$Following_ID = $_GET['Following_ID'];
//connection infi
$con=mysqli_connect("localhost","root","PASS","TABLE");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
//SQL to select all fields from appointment table
$result = mysqli_query($con,"SELECT * FROM Followers
WHERE Following_ID='$Following_ID' AND Follow_Status='acce' AND Followers_Requested_Game NOT LIKE '%$Following_ID%' AND (Follower_Game='truth' OR Follower_Game='rate') ORDER BY Game_Time DESC");
//echo all in array
while($row = mysqli_fetch_array($result))
{
$time = $row['Game_Time'];
humanTiming ($time);
echo 'event happened '.humanTiming($time).' ago';
}
function humanTiming ($time)
{
$time = time() - $time; // 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':'');
}
}
}
//close connection
mysqli_close($con);
?>
I have the solution here:
<?php
//AJAX REQUEST
$Following_ID = $_GET['Following_ID'];
//connection infi
$con=mysqli_connect("localhost","root","PASS","TABLE");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
//SQL to select all fields from appointment table
$result = mysqli_query($con,"SELECT * FROM Followers
WHERE Following_ID='$Following_ID' AND Follow_Status='acce' AND Followers_Requested_Game NOT LIKE '%$Following_ID%' AND (Follower_Game='truth' OR Follower_Game='rate') ORDER BY Game_Time DESC");
//echo all in array
while($row = mysqli_fetch_array($result))
{
$times = $row['Game_Time'];
$time = strtotime($times);
humanTiming ($time);
echo 'event happened '.humanTiming($time).' ago';
}
function humanTiming ($time)
{
$time = time() - $time; // 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':'');
}
}
//close connection
mysqli_close($con);
?>
I can't comment as I don't yet have 50 rep so I'll have to do that here but it seems that #Marc B is right when he said:
($time) correponds to your date being Jan 1/1970
Whenever I'm trying to do something with a date and it pulls through that date (1st Jan 1970) I know that I'm not matching up the formats of time. So I'm advising 3 things:
1) Bug test - eliminating all possibilities
Output $time from this segment of your code: $time = $row['Game_Time'];
Check that this is coming out as a unix timestamp (currently 1392430174 as I write)
As time() is in unix timestamp format this will mean that you are deducting correctly and the line $time = time() - $time; will also be in unix timestamp format.
2) The probable
If I had to take a guess I would say that $time or $row['Game_Time'] is not in unix timestamp format which means you should convert it using strtotime($time) and then do the calculation ($time = time() - $time; // to get the time since that moment). Test the output of this. With coding one thing is for absolute certain - you will get bugs. So you have to work on the system of deducing the answer based on a series of logical tests. It really is like trapping a bug with a glass!
3) A few tips
I would do yourself a favour and avoid potential problems with variable names. Why not call this line:
$time = time() - $time; // to get the time since that moment
like this:
$time_difference = time() - $time; // to get the time since that moment
.. or whatever as I have previously had problems in redefining a string as part of itself like this - particularly when passing parameters.
Also wouldn't the $tokens array be more standardised switching the seconds to the value and the time name, e.g. "year" to the key. And maybe use something easier to read so there are no mistakes with the numbers, e.g.
$tokens = array();
$tokens['second'] = 1;
$tokens['minute'] = 60*$second;
$tokens['hour'] = 60*$minute;
$tokens['day'] = 24*$hour;
$tokens['week'] = 7*$day;
$tokens['month'] = 30*$day;
$tokens['year'] = 365*$day;
Just suggestions but the main thing is that if it is just you working with it you can find yourself around, etc. Oh and get anything in the open in a function - just call it from the outside. All good stuff though!_
I'm passing this function a mysql datetime and it is returning nothing. Is mysql datetime not compatible with strtotime()? I assume that the foreach loop is ending and the return variable is not being called, but why?
function timeAgo($time) {
$time = time() - strtotime($time); // to get the time since that moment
$tokens = array (
1 => 'second',
60 => 'minute',
3600 => 'hour',
86400 => 'day',
604800 => 'week',
2592000 => 'month',
31536000 => 'year'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').' ago';
}
}
Update This is the code that gets it from the database, there are no quotes in the datetime string.
while ($row = mysqli_fetch_assoc($result)) {
$commentTime = $row["time"];
$commentComment = $row["comment"];
$commentCommenter = $row["commenter"];
}
And this is the code to echo it: echo '<h3 class="party-time">'.timeAgo($commentTime).'</h3>';
The problem was a timezone issue. I was manually setting the date in the SQL server I was using which set the datetime to my local time, but the server's timezone was -3 hours, causing issues.
We cannot tell what $time holds exactly, but when you feed an ISO-8601 date to strtotime, it works fine:
php > echo strtotime("2013-08-01 12:00:00");
1375351200
I have this function that calculates the time elapsed since a row was added into a database:
function added_on($time){
$now = time();
$time = $now - $time;
$blocks = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($blocks as $unit => $size) {
if ($time < $unit)
continue;
$nrOfUnits = floor($time / $unit);
return $nrOfUnits.' '.$size.(($nrOfUnits>1)?'s':'');
}
}
The problem with this is that is not accurate, i.e has an error of about 7 hours behind.
When called on a current time, it returns like: added 7 hours ago.
Function is called as:
$posted_on = strtotime($row['created_at']);
echo 'added '.added_on($posted_on).' ago';
Where $row['created_at'] is MySQL Date type
thank you
At first blush I'm guessing different time zones. A different way to accomplish the same task in pure MySql follows:
select time_to_sec(timediff(now(), created_at)) as seconds_ago from `table_name`
To help you debug more you can check and set the timezone of the mysql server with the following (docs):
-- Check the global and session time_zone settings
select ##global.time_zone, ##session.time_zone;
-- Set the time zone to GMT -5 hours (EST):
set SESSION time_zone = '-5:00';
I am trying to calculate time passed since a comment is posted. I found a function for this and it's working well
But I just noticed the time shown to user is wrong because of his/her timezone. I did some research and the solution seems to be passing the user's timezone offset to the php page using a javascript function called getTimezoneOffset.
the problem is that I can't manage to use this Offset to make a timezone and use it on that function I linked above. With the help of another code is what I could gather so far :
function humanTiming ($time,$offset)
{
$isDST = 1; // Daylight Saving 1 - on, 0 - off
$timezoneName = timezone_name_from_abbr('', intval($offset, 10) * 36, $isDST);
$date = new DateTime($time, new DateTimeZone($timezoneName));
$time = strtotime($date);
$time = time() - $time; // 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':'');
}
}
And let's call the function like this :
echo humanTiming ($row['date'],"-240");
note : -240 is the value I get from running that javascript function, So it is probably my timezone offset.
First issue: It seems the value -240is invalid and something like -0500 works.
Second issue: even If I try with the valid offset value, the function returns 42 years
Not sure how this 42 years is calculated but its totally wrong.
A couple of problems:
The Javascript function getTimezoneOffset() returns the timezone offset in minutes, however timezone_name_from_abbr() expects the offset in seconds. So in your example of -240 that is actually -4 hours or -14396 seconds. You can fix your code by changing the math a little:
$timezoneName = timezone_name_from_abbr('', intval($offset) * 60, $isDST);
Since you've started using the DateTime object, you can't then use strtotime to get the Unix timestamp. Instead you need format():
$date = new DateTime($time, new DateTimeZone($timezoneName));
$time = $date->format('U');
This should get the result you are after. You were getting 42 years because the time was set to 0 (strtotime($date) evaluated to false) which is Unix epoch - 1970.
You could offset everything like so:
$today=new DateTime("-$offset minutes");
$tomorrow=new DateTime("+1 day-$offset minutes");