I have problems comparing dates between a date created with new dateTime () in php, and a date taken from a DATETIME field of a Mysql table.
With the following code, save a date in a DATETIME field of a MySQL table:
$now = new DateTime();
$update = $mysqli->query('INSERT INTO bonus (idplayer,lastlogin) VALUES ("'.$_GET["idplayer"].'","'.$now.'")');
Then I would like to retrieve the date from the tables and compare it with a date created using the php code:
$resetTime = new DateTime();
date_time_set($resetTime, 12, 00, 00);
$lastLogin = $mysqli->query('SELECT lastlogin FROM bonus WHERE idplayer = "'.$_GET["idgiocatore"].'"');
if ($resetTime < $lastLogin) {
echo "OK!<br>";
}
Using this code I can't comparate the dates because I get an error (I can't even do an echo of the date retrieved from the table).
Can anyone tell me where I'm wrong and how can I solve the problem?
Try this
$resetTime = (new DateTime)->format('Y-m-d 12:00:00'); //need it as a string
//$resetTime = date('Y-m-d 12:00:00'); //-- this is fine too
$stmt = $mysqli->parpare('SELECT lastlogin FROM bonus WHERE idplayer = ?');
$stmt->bind_param("s", .$_GET["idplayer"]);
$stmt->execute();
list($lastLogin) = $stmt->get_result()->fetch_array();
if ($resetTime < $lastLogin) {
echo "OK!<br>";
}
Basically your comparing the query result set, to your timestamp, instead of the value of the first column of the first row. Consider you code:
$lastLogin = $mysqli->query('SELECT lastlogin FROM bonus WHERE idplayer = "'.$_GET["idgiocatore"].'"');
if ($resetTime < $lastLogin) {
mysqli::query
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object. For other successful queries mysqli_query() will return TRUE.
https://www.php.net/manual/en/mysqli.query.php
Your also full of SQL Injection errors, an input such as this:
$_GET["idgiocatore"] = '" OR 1 ORDER BY lastlogin DESC LIMIT 1 --'
Will turn your query into this
'SELECT lastlogin FROM bonus WHERE idplayer = "" OR 1 ORDER BY lastlogin DESC LIMIT 1 -- "'
Everything after the -- is a comment so we can ignore that ending ". This avoids creating a syntax error, and is a very common tactic (nothing new).
This will select all records from the DB because Anything plus OR 1 is always true, then it will sort them by your lastlogin value DESC so the highest value is first and Limit to 1 return row, well just because I can. Basically this will satisfy your if condition if ($resetTime < $lastLogin) Which I guess is a "good thing" (well for me, the haxor).
Essentially this is because you are just pasting user input right into the SQL, so it becomes part of the command if formulated correctly (not a good thing for you).
Anyway Hope it helps you.
*PS it's been an age (like 6 years) sense I used MySqli (normally I use PDO) so forgive me any errors there, most of that came from a basic tutorial over at W3Schools
One last thing instead of setting the time, consider removing it altogether with the MySql DATE() function:
$resetTime = (new DateTime)->format('Y-m-d');
//...
$stmt = $mysqli->parpare('SELECT DATE(lastlogin) FROM bonus WHERE idplayer = ?');
Related
in my query
$stmt = $this->conn->prepare("SELECT p_index,m_id,DATE_FORMAT(trdDtTm, '%Y%m%d') as trdDtTm FROM ".$this->itemsTable." WHERE m_id = 2");$stmt->bind_param("i", $this->m_id);
result
{"items":[{"p_index":7,"m_id":"2","trdDtTm":"20220203"}}
However, if you search after changing the trdDtTm format, the results will not come out. How do I fix it?
$stmt = $this->conn->prepare("SELECT p_index,m_id,DATE_FORMAT(trdDtTm, '%Y%m%d') as trdDtTm FROM ".$this->itemsTable." WHERE m_id = 2 and trdDtTm = 20220203");
$stmt->bind_param("ii", $this->m_id, $this->trdDtTm);
no items.. how to fix it?
trdDtTm is a datetime column.
WHERE trdDtTm = 20220203
compares a datetime with a number hence. This makes hardly sense. Maybe you hope for the DBMS to magically match the two, but you shouldn't. Compare with a date literal instead:
WHERE trdDtTm = DATE '2022-02-03'
And if you want to find all rows on that date regardless of the time (the above only finds midnight, as DATE '2022-02-03' is considered equal to TIMESTAMP '2022-02-03 00:00:00'), do:
WHERE trdDtTm >= DATE '2022-02-03' AND trdDtTm < DATE '2022-02-04'
I have 5 records in mysql database and these records have recorded date within this date interval.
$year=2015;
$month=8;
$datefrom=1;
$dateto=31;
$startdate='$year-$month-$datefrom 00:00:00';
$enddate='$year-$month-$dateto 23:59:59';
So I write a query to get these records out like this:
$sql = "SELECT id FROM newpost WHERE email=:email AND :startdate <= poststart <= :enddate AND postapproved=1";
Given that poststart column in table newpost has SQL Datetime format like this: "Y-m-d H:i:s".
But when I changed variable $year = 2016, I still got 5 results? It should return no record. Because those 5 records are recorded between 1 - 31 August 2015.
So I thought I did something wrong in the sql query especially the comparing date part but I could not configure out how to fix it?
Please help!
You can use BETWEEN in your query
$sql = "SELECT id FROM newpost WHERE email=:email AND (poststart BETWEEN :startmonth AND :endmonth) postapproved=1"
Use single quotes to wrap your date values
$sql = "SELECT id FROM newpost WHERE email=:email AND poststart BETWEEN ':startdate' AND ':enddate' AND postapproved=1";
A couple quick things to check to make sure it's not a syntactical error:
Your variable names don't match up. You defined startdate and enddate, but then in the query you used startmonth and endmonth.
You should probably also use leading zeros in your month and day, i.e.:
$month='08';
$datefrom='01';
The only thing that I have left for my assignment is to show the amount of new transactions since the user last visited his statistics dashboard, I thought I understood the concept of this fairly well, but it seems like I'm running into a problem.
This problem is that the current-date that the user has, and the current-timestamp that the SQL uses are not one and the same. (I would assume this varies based on time-zones?)
I guess what I'm looking for is what time=zone MySQL stores the DATETIME (Current Timestamp) field in, so I can get the current time-stamp of the user, his time-zone, and attempt to perform logic to make them the same.
Or is there an easier way around this? I'm currently using the DATETIME format in my dashboard to display information on purchase dates, which is formatted like so 2015-01-12 01:02:18 inside of a table.
Perhaps my query is just wrong, who knows:
function getNewTransactions($connection, $user) {
$statement = $connection->prepare("SELECT `lastcheck` FROM `login` WHERE 1");
$statement->execute();
while($row = $statement->fetch()) {
$d = $row['lastcheck'];
}
$statement = $connection->prepare("SELECT * FROM `transactions` WHERE `date` > :d");
$statement->bindParam(":d", $d);
$statement->execute();
$transactions = 0;
while($row = $statement->fetch()) {
$transactions++;
}
$date = date("Y-m-d H:i:s");
$statement = $connection->prepare("UPDATE `login` SET `lastcheck` = '{$date}' WHERE `username`=:name");
$statement->bindParam(":name", $user);
$statement->execute();
return $transactions;
}
If I swap the > around to < it does show older transactions, but they're off by a few hours.
http://php.net/manual/en/function.date-default-timezone-set.php
This should help you out with setting the timezone.
You can get the timezone from MySql with
SELECT ##system_time_zone;
or get the +/- offset from GMT with
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
In your situation you can try something like this
SELECT convert_tz(`lastcheck`, 'TIMEZONE_LASTCHECK_IS_STORED_IN', ##system_time_zone, ) as lastcheck
FROM `login`
WHERE 1
But ideally, all the datetimes in the database should be stored in the same timezone. That would eliminate your current problem. You could achieve this with ...
SELECT ##system_time_zone
... and save the value into the PHP variable $db_timezone_code
... then replace the $date assignment with ...
$db_timezone = new DateTimeZone($db_timezone_code);
$now = new DateTime('now');
$now->setTimeZone($db_timezone);
$date = $now->format('Y-m-d H:i:s');
... $date is now converted from the PHP servers timezone
... to the databases default timezone.
I want that my PHP checks if the time in the mysql db is the same, and if not that it will be changed.
This is what I got:
<?php
$last_time_check=mysqli_query($con,"SELECT `time` FROM `servervars`");
if((time()-$last_time_check) >=1)
{
mysqli_query($con, 'UPDATE `servervars` SET `time`='.$time.' WHERE ID=1');
}
?>
$con is the connection to the DB.
Current value 'time' in servervars: 1412448339
Value 'ID' is 1
I do something wrong, but I just cannot find where it's going wrong.
The Fix
I've removed the variable $last_time_check and only checked if the time could get changed. If this happends then it will send another message to the client.
mysqli_query($con, 'UPDATE `servervars` SET `time` = UNIX_TIMESTAMP() WHERE ID = 1 AND UNIX_TIMESTAMP() - `time` >= 1');
if ($con->affected_rows)
{
// at least 1 second has elapsed, do stuff
}
MySQL has an equivalent to time(), its the function UNIX_TIMESTAMP(). Differently though, it can take a DATETIME as parameter to convert it into UNIX time, but when used without parameters its the same as UNIX_TIMESTAMP(NOW()).
UPDATE servervars SET time = UNIX_TIMESTAMP() WHERE ID = 1
Update
Ok so about the other issues. You are doing it all wrong. mysqli_query does not return the value directly. To fetch the value of time from the database, you need 3 steps:
$result = $con->query('SELECT `time` FROM `servervars` WHERE ID = 1'); // fetch result set
$row = $result->fetch_row(); // fetch a row from the result set, as an array
$last = $row[0]; // get the first element from the row you just fetched
Notice $con->query() can fail if theres a problem with the connection, the database, the table, or the query syntax itself, and $result->fetch_row() can fail if there are no results for the query. You should validate them before proceeding to the next step.
Alternatively, you can do this:
$con->query('UPDATE `servervars` SET `time` = UNIX_TIMESTAMP() WHERE ID = 1 AND UNIX_TIMESTAMP() - `time` >= 1');
if ($con->affected_rows)
{
// at least 1 second has elapsed, do stuff
}
This way we shortened your solution to a single query, that updates the field if necessary and report back that it happened or not..
Using the code below, I'm having trouble checking whether a specified date exists in a MySQL 'date' column.
$data = array(1367971200);
$s=$dbh->prepare("
SELECT DISTINCT
`date`
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?
");
if ($s->execute($data)) {
if ($s['date'] == null) {
return false;
}
return true;
}
It's returning false, despite the fact that I can see the date '2013-05-08' displayed in phpMyAdmin.
The table itself contains 70+ entries for that date. It always will do, if it contains any at all, but I just want to know whether it exists or not at this stage.
The date field is a MySQL 'date' type. I'm suspecting that the bug is in my structuring of the PDO calling of the query.
UPDATE
Updated $r['date'] to `$s['date']. I suspect that I still have an issue with the structure of that, but probably need to fix the query so that it gives us results before focusing on this.
Also tried running the query against the database directly and got an empty resultset, despite being able to see that the target date exists. Still baffled!
Try this
$data = array(1367971200);
$s=$dbh->prepare("
SELECT COUNT(`date`) as c_date
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?");
if ($s->execute($data)) {
$result = $s->fetch(PDO::FETCH_ASSOC);
if ($result['c_date'] > 0) {
return false;
}
return true;
}
You can't select a whole day with UNIX timestamps because of their more accurate nature (i.e. seconds), you would need the textual version:
$data = array(date('Y-m-d', 1367971200));
$stmt = $dbh->prepare("SELECT COUNT(*)
FROM `report_coa_bal_hist`
WHERE `date` = ?
");
$stmt->execute($data);
$count = current($stmt->fetchAll(PDO::FETCH_COLUMN, 0));
return $count > 0;
Take note of any timezone differences between the server that runs your script and the database server itself.
there are many flaws with your code, not one:
format of the value you are checking
way you are checking in SQL
the way you are getting result
So, the code have to be
$data = array('2013-05-07');
$sql = "SELECT 1 FROM report_coa_bal_hist WHERE `date` = ? LIMIT 1";
$stm = $dbh->prepare($sql);
$stm->execute($data);
return $stm->fetchColumn();