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!_
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'];
I found a code that transform a timestamp from when a user last logged in. It really short but works just fine displaying x seconds, 2 days, etc.
The problem is that i wish to transform the first x minutes (max 5min) to say <div class="green">ONLINE</div>
heres the php:
<?php
function humanTiming ($time)
{
$time = time() - $time; // to get the time since that moment
$time = ($time<1)? 1 : $time;
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
// Tried to replace seconds with <div class="green">ONLINE</div>
// but will end up looking like x ONLINEs where x = seconds
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
echo humanTiming( strtotime($user_last_life) );
?>
Followup question :
What is the most secure and best way to update a database with timestamp?
I have problems having it update after login but have added this code in my head.php
$updated_life_id = htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
$set_last_life = "UPDATE users SET last_life = time() WHERE id = '$updated_life_id'";
$datab->query($set_last_life);
if(strtotime($user_last_life) >= time()-300) // 300 seconds = 5 minutes
{
echo '<div class="green">ONLINE</div>';
}
And for your database question
How can I prevent SQL injection in PHP?
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.
I found a function form SC to output human readable time. like `
5 hours, 1 hour, 5 years, etc
function human_time ($time)
{
$time = time() - strtotime($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 I have time as string: 2013-09-28 20:55:42
when I call this function human_time('2013-09-28 20:55:42')
then it return nothing, why ?
I have added strtotime in above function.
Please tell me what is wrong.
This is no ready-to-use code, but rather supposed to guide you the right way:
$then = new DateTime($time); // you might need to format $time using strtotime or other functions depending on the format provided
$now = new DateTime();
$diff = $then->diff($now, true);
echo $diff->format('Your style goes here');
See DateTime Manual for further documentation or feel free to ask here.
Edit: Link fixed.
Use example :
echo time_elapsed_string('2013-05-01 00:22:35');
echo time_elapsed_string('2013-05-01 00:22:35', true);
Output :
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
Link to the function.
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