MySQL NOW() does not match PHP timezone - php

I made an Email Verification Link where the link will valid for only the next 10 minutes from the time of mail sent but my code as given below is not works.
Wait, I show all the related threads on StackOverflow and offcourse I got the same question-related post but I also do that result answer but it not works for me, so that I posted this question might somebody have the same issue and it will help to others.
Please do not marks it as duplicate and under review mode, and try to understand my query.
Please help me how I fix this issue and what would be correct code. :(
MY Code is Below : -
Other Code
date_default_timezone_set('Asia/Kolkata');
tokenExpire formats: (new DateTime('+10 minutes'))->format('Y-m-d H:i:s')
DB Structure[name as signup]
-----------------------------------------------------
Email | token | tokenExpire |
----------------------------------------------------
abcd#domain.com | {randNum} | 2019-10-19 09:42:10 |
-----------------------------------------------------
PDO Statement
$sql = $con->prepare("SELECT `Email`,`token` FROM `signup` WHERE Email= :1 AND token= :2 AND tokenExpire > NOW()");
$sql->execute(array(
':1' => $emailid,
':2' => $tokenum
));
if ($sql->rowCount() > 0) { echo "Link Is Valid"; }
else { echo "Link Expired"; }
I expects it must show time expire or valid info behalf of my code but it not works, and show Link valid even the time has past.

Looks like you have different Apache (or whatever you are running on) and MySQL time zones.
Make a short script, change PHP timezone, print DateTime value and at the same time insert row to MySQL with NOW() and check if time in MySQL and printed one differs.
Info how to deal with MySQL time

This seems to be related to time-zone differences, and you should be able to change the settings of both PHP and MySQL, for example based on another answer, you can configure PHP like below:
<?php
define('TIMEZONE', 'UTC');
date_default_timezone_set(TIMEZONE);
and for MySQL you should run a query like below:
<?php
$now = new DateTime();
$mins = $now->getOffset() / 60;
$sgn = ($mins < 0 ? -1 : 1);
$mins = abs($mins);
$hrs = floor($mins / 60);
$mins -= $hrs * 60;
$offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
//Your DB Connection - sample
$db = new PDO('mysql:host=localhost;dbname=test', 'dbuser', 'dbpassword');
$db->exec("SET time_zone='$offset';");
The PHP and MySQL timezones are now synchronized within your application. No need to go for php.ini or MySQL console!
But you may want to convert the timezone before showing to users which for example could look like below:
/**
* Converts server date to user's local-date.
*/
function GetUserDate($date, $format = 'n/j/Y g:i A', $userTimeZone = 'Asia/Kolkata') {
// Use previous TIMEZONE constant just in case
// (If "date_default_timezone_set(TIMEZONE)" is called
// it's not required to pass "DateTimeZone" in below line)
$dateTime = new DateTime($date, new DateTimeZone(TIMEZONE));
$dateTime->setTimezone(new DateTimeZone($userTimeZone));
return $dateTime->format($format);
}
Note: above should solve your problem but any existing value on your tokenExpire column might still be having a different time-zone (only newly created entries will follow your new time-zone settings).
(Based on an article on SitePoint)

Related

Check if the time is more than 24h and show it

I have in my MSSQL database a column with datatype of datetime which contains some dates in this format 2021-01-11 19:58:04.277.
This is a voting system, the idea is that the users can only vote once every 24 hours.
Every time they vote this table is updated with a new record and a new date is added with the corresponding user.
I want to display a message that says how many hours left to place the next vote.
This is the code I am trying to use:
/**
* Get Votes Time
*
*/
public function getVoteRemainingTime($account) {
date_default_timezone_get();
$currentTime = date('Y-m-d H:i:s');
$sql = "SELECT VoteDate FROM dbo.vote WHERE Account = :account ORDER BY logid DESC";
$query = $this->db->prepare($sql);
$query->execute(array(':account' => $account));
$voteDate = $query->fetch(PDO::FETCH_OBJ);
$timeLeftVote = strtotime($currentTime) - strtotime($voteDate->VoteDate);
if($timeLeftVote > 86400) {
return '<strong>Vote Available!</strong>';
} else {
return $timeLeftVote;
}
}
But it is displaying the wrong information. What I am doing wrong? I would appreciate your help.
Thanks!
you need declare format parameter of the date() like date('Y-m-d H:i:s')
date_default_timezone_get();
$currentTime = date('Y-m-d H:i:s');
$timeLeftVote = strtotime($currentTime) - strtotime('2021-01-11 19:58:04.277');
if($timeLeftVote > 86400){
echo 'Vote available';
}else{
echo $timeLeftVote;
}
Instead of SELECT VoteDate FROM dbo.vote
Can you do the calculation on the time difference at source in the database using
SELECT VoteDate, DATEDIFF(HOUR, VoteDate, GETDATE()) as HourDifference from dbo.vote
As I cannot check your database query, I only checked the rest of the code and it seems to work (as Fikri F mentioned in the comments of this post) if I replace $voteDate->VoteDate by a static date.
So please provide more information. You could output the current time and the previous vote time from the database as strings, and for both dates as well the result of strtotime, and in the end the result of the method. Then please explain, what the wrong behaviour is. By this, we can narrow down the problem either to the DB query or to the PHP code.
(I would write this as a comment, but I have not enough reputation.)

php date timezone issue

I have PHP site which is running with some custom script. I store a last query date in the DB as UTC, like this:
$query = "UPDATE mytable SET last_query = UTC_TIMESTAMP() WHERE id = 1";
When the script executes, it grabs that last date and converts it to the local tz like this:
$sql = "SELECT last_query FROM mytable WHERE id = 1"; // grab date
$result = $dbo->query($sql);
$row = $result->fetch();
$last_query = new DateTime($row['last_query'], new DateTimeZone('UTC')); // build datetime
$last_query->setTimezone(new DateTimeZone('America/Denver')); // set to local tz
$last_query = $last_query->format('Y-m-d\TH:i:s'); // format
$this->log('info', "Last queried: ".$last_query);
In my phpinfo(), date.timezone = America/Denver but the line for Default timezone shows UTC.
I have an older logging script that prints a log line preceded by the date produced using date, like this: $time = date( $this->DateFormat );
The problem is that in the log file, it shows the last query date as incorrect:
2016-07-05 12:00:02 - INFO --> Last queried: 2016-07-05T18:00:02
The date of the log message (2016-07-05 12:00:02) is correct-- the date of the last_query as you can see is 6hrs ahead (or UTC time).
What am I missing in my date conversion (or possibly in the PHP ini?) that is causing this mismatch? I'm assuming that I'm wrong to instantiate the DateTime object with the UTC timezone, but despite reading a lot of documentation on timezones I am still unclear.
EDIT: the last_query column is a mysql TIMESTAMP field

PHP : comparing fetched date with today

i'm saving time for first login ,now when user logs in i enter time using NOW() function, that saves time in this format (data type is DATETIME.
2015-12-24 15:47:30
Now logic is like every login is first login so i've to check if there already exists an entry for today to check that i fetch time explode it and get time like this
$logintime= mysqli_query($connection,"SELECT loggedin from employees");
$loggedin_time= mysqli_fetch_assoc($logintime);
$Date = $loggedin_time['loggedin'];
$loggedin_time_converted= explode(" ",$yourDate) ;
$ConvertedDate = $loggedin_time_converted[0];
last line returns 2015-12-24 now i've date
$today= time();
$DateToday= date("Y-m-d",$today);
$DateToday also returns me same format and same date now i need your help me to compare these dates , if they are equel i dont uopdate database if they are not i will , Pleas help me how do i compare these values
You can do the test in MySQL
$result = mysqli_query($connection, "SELECT DATE(loggedin) = CURDATE() AS logged_in_today FROM employees");
$row = mysqli_fetch_assoc($result);
if (!$row['logged_in_today']) {
// code to update database
}
Wow, you've done all the hard stuff to get the problem to the point of being a simple comparison of 2 strings. This is all you need to do to get over the finish line ...
if ($ConvertedDate !== $DateToday) {
// update the database
}
You can use Php Built In function "Date Difference."
Code Seems Like As Follow:-
$today= time();
$DateToday= date("Y-m-d",$today);
$diff = date_diff($today,$DateToday);
echo "$diff days";
This will return values something like +12 days or something else.

How would I go about timing between status changes in php?

When the status changes to prepare/preparing, the timer begins. I then want to stop the timer and calculate the difference when the status changes to ready, and store it as time in the database. Ive tried various ways but can't seem to get it working, what am I doing wrong? Thanks
if(isset($_POST['prepare'])){
$_SESSION['startTime'] = time();
$question2="UPDATE `order` SET orderStatus='Preparing', idEmployee='$_SESSION[id]' WHERE idorder='$_POST[id]'";
$sth = $db->prepare($question2);
$sth->execute();
}
if(isset($_POST['ready'])){
$total = time() - $_SESSION['startTime'];
echo date('h:i:s', $total);
$question2="UPDATE `order` SET orderStatus='Completed', timeCompleted='$total' WHERE idorder='$_POST[id]'";
$sth = $db->prepare($question2);
$sth->execute();
}
edit: I overcame the issues I was having by simply using a method within the DateTime class. I began by recording the time from when the order was taken, I also recorded the time of when the order was completed. I then used the method diff() to calculate the difference between the 2 recorded times and stored the results in my db.
if(isset($_POST['prepare'])){
$_SESSION['startTime'] = new DateTime();
$question2="UPDATE `order` SET orderStatus='Preparing', idEmployee='$_SESSION[id]' WHERE idorder='$_POST[prepare]'";
$sth = $db->prepare($question2);
$sth->execute();
}
if(isset($_POST['ready'])){
$endTime = new DateTime();
$i = $_SESSION['startTime']->diff($endTime);
$end = $i->format('%h:%i:%s');
$question2="UPDATE `order` SET orderStatus='Completed', timeCompleted='$end' WHERE idorder='$_POST[ready]'";
$sth = $db->prepare($question2);
$sth->execute();
}
Replace $total = time() - $_SESSION['startTime'] with $total = time() - strtotime($_SESSION['startTime'])
And add session_start(); to the top of your code if you didn't
Then it will work.
If both prepare and ready are actioned on the same machine by the same person (within the same session) - this code should work. If you believe all this to be true - I would check to make sure the session variables are being set print_r($_SESSION)
However, I would recommend when you update orderStatus to 'Preparing', creating a new column called timeStarted and update that to time(), then when you are updating to 'Completed' set timecompleted also to time()
You can then easily work out the difference, as currently (if this code did work timeCompleted is actually timeTaken) - for which you could even add a 3rd column which is the difference between the two for easy reporting.
Doing it this way means if it takes longer than the session or the computer restarts / re login the startTime is not lost

comparing timestamps

HI, My php is very rusty and I can't quite remember how to do this.
I have a script that i only want to call every 15 minutes. I've created a table called last_updated. What I want to do is have some code at the top of my script that queries this last_updated table and if now() minus the last updated is greater than 15 minutes then run the script and also update last_updated to now...if it isn't don't run the script. Does this make sense?
Now I know when I'm updating last_updated I need to use now() To put a new timestamp in but I;m not sure how to do the comparing of now with the db value to see if it's greater then 15 mins.
Any ideas
<?php
$pdo = new PDO('mysql:host=your_host;dbname=your_database', $user, $password, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
// query the database. change
$stmt = $pdo->query('SELECT UNIX_TIMESTAMP(last_updated_date) FROM last_updated ORDER BY last_updated_date DESC LIMIT 1');
$lastUpdatedTimestamp = $stmt->fetch(PDO::FETCH_COLUMN);
if ((time() - $lastUpdatedTimestamp) > (60 * 15)) {
touch($file);
// do stuff
}
time() gives you the current time in seconds. You should probably unroll 60 * 15 to 900, I just provided it with both numbers to illustrate what was going on.
Also, a file might be better for this than a database table. Have a look at the touch()
function. It changes the modification time of a file, or creates an empty file with the current time as the mod time if it doesn't exist. You can check the file mod time with filemtime()
<?php
$lastUpdated = null;
$file = '/path/to/writable/file/with/nothing/in/it';
if (file_exists($file)) {
$lastUpdated = filemtime($lastUpdated);
}
if (!$lastUpdated || (time() - $lastUpdated) > 900) {
touch($file);
// do stuff
}
You seem to use MySQL as the DBMS. In that case and if you want you can let MySQL do most of the work:
SELECT
pit < Now()-Interval 15 Minute as mustUpdate
FROM
last_updated
WHERE
siteId=?
pit is your DateTime field and siteId is some condition you may have if you store more than one record in the table (which sounds like a good idea to me).
The result (if there is such a record with siteId=?) contains a field mustUpdate which either contains 0 or 1, 1 indicating that the value of pit is more than 15 minutes in the past.

Categories