How to detect that time is past midnight? - php

Im coding a text-based mafia game in norwegian and need help with time detection. So here's the deal. In way to delete a mysql-record if time since a player bought the product is over midnight (24 hours clock). Here is what I tried, but in unsure it's the best method:
// Har livvakt? (Has bodyguard)
if($this->isTheftProtected($user_id)){
$sql = mysql_query("SELECT * FROM `UserTing` WHERE t_meta = '2' AND t_owner = '".$user_id."'");
$rows = mysql_fetch_array($sql);
$timeThen = date("Hi", $rows["t_time"]);
$theNow = date("Hi");
if($timeThen > 0000){
// Slett produktet <- Delete here... past midnight.
} else {
// Behold.
}
} else {
return;
}
So, is there a better way. Should time() be considered to be used? Its really how to do this that my question is.
Regards. ;)

You might need to add cronjob or just run this query before SELECT to delete old records.
DELETE FROM `t1` WHERE DATE(`created`) < CURDATE();
JOINS also can be used...

http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestampdiff
mysql> SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
Returns 128885
So logically;
SELECT * FROM UserTing WHERE TIMESTAMPDIFF(SECOND, NOW(), t_time) >= (60 * 60 * 24) AND t_owner = {$user_id}
Shows values that 24 hours older than the current time, for t_owner.
Edit 3: Make sure you are always using MySQL time comparisons with MySQL, or PHP. But not both, as there is a allowed time variance allowed between the two. (They can sometimes be off by as much as a hour with no errors.)

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.)

How to correctly manage a bidding system with PHP?

I've developed a bidding system with PHP and MySQL.
It works good in the most of the cases, but I've noticed there is a problem when offers are really close.
$now = DateTime::createFromFormat('U.u', microtime(true));
$dateMicroTime = date("Y-m-d H:i:s").".".$now->format("u");
$amountToRaise = 100;
$lastOffer = $bid->lastOffer();
//if there is an offer yet
if($lastOffer){
$newPrice = $lastOffer->getAmount()+$amountToRaise;
//else is the first offer
}else{
$newPrice = $amountToRaise;
}
//if the user is not the last bidder
if($user->getId() != $lastOffer->getUserId()){
$bidOffer = new BidOffer();
$bidOffer->setBidId($bid->getId());
$bidOffer->setUserId($user->getId());
$bidOffer->setAmount($newPrice);
$bidOffer->setTime($dateMicroTime);
$bidOffer->save();
//if this is not the first offer I give back the money to the previous user
if($lastOffer){
$lastUser = $lastOffer->user();
$lastUser->setCash($lastUser->getCash()+$lastOffer->getAmount());
$lastUser->save();
}
}
The code works well when offers are done in different moments, but users offer in the same seconds for example: 18:00:01.1299022 and 18:00.02.1222377
The user with previous offer doesn't receive back the offer.
How can I fix this? I've tried to use a temporary variable to block the statement temporary until every query are executed, but no success.
I would separate dateTime from microtime and would not use $dateMicroTime = date("Y-m-d H:i:s").".".$now->format("u");.
You can than use microtime to extract the last bidder. This can be done by adding a bid_utime column in your DB. If you are looking all the bidders for one auction chronologically ORDER BY table.bid_utime DESC.Last bidder can be found by ORDER BY table.bid_utime DESC LIMIT 1 as a return from $lastOffer = $bid->lastOffer();.
This also means you wont be saving your bids with: $bidOffer->setTime($dateMicroTime);but with something like:
$bidOffer->setDate($date); and $bidOffer->set_uTime($now);
But you can also skip all of this and return only the last entry from the bid table with SELECT * FROM bid_Table ORDER BY ID DESC LIMIT 1 and forget about dateMicroTime and microtime. Hope this helps.

Time Calculations with MySQL

I'm writing a time logging programme for a client who is a piano tuner, and I've written the following PHP code to give a record a status of 'to do':
$last_tuned = '2017-01-05';
$tuning_period = 3;
$month_last_tuned = date('Y-m', strtotime(date('Y-m-d', strtotime($last_tuned))));
$next_tuning = date('Y-m', strtotime($month_last_tuned.(' +'.$tuning_period.' months')));
if (time() > strtotime($next_tuning.' -1 months')) {
if (time() > strtotime($next_tuning)) {
return 'late';
} else {
return 'upcoming';
}
}
As you can see, the $last_tuned variable is of the date(YYYY-MM-DD) format. This is then converted to a (YYYY-MM) format.
Once convered, an additional number of months, identical to $tuning_period is then added to the $month_last_tuned variable giving us a month and year value for when we need to add a new record.
If the current time (found with time()) is greater than the $next_tuning variable - 1 month, it returns that the task is upcoming. If it's after the $next_tuning variable, it returns that the task is late.
I now have to write a MySQL query to list the items that would return as upcoming or late.
How would I write this in MySQL? I'm not very good with MySQL functions, and some help would be much appreciated.
My attempt at the logic is:
SELECT * FROM records
// The next lines are to get the most recent month_last_tuned value and add the tuning_period variable
WHERE
NOW() > (SELECT tuning_date FROM tunings ORDER BY tuning_date ASC LIMIT 1)
+
(SELECT tuning_period FROM records WHERE records.id = INITIAL CUSTOMER ID)
I know that that is completely wrong. The logic is pretty much there though.
My database schema is as follows:
I expect the rows returned from the query to be on-par with the 'late' or 'upcoming' values in the PHP Code above. This means that the rows returned will be within 1 months of their next tuning date (calculated from last tuning plus tuning period).
Thanks!
You'd probably be better off with using the DateTime object instead of manipulating date strings.
$last_tuned = '2017-01-05';
$tuning_period = 3; // months
$dt_last_tuned = DateTimeImmutable::createFromFormat('Y-m-d',$last_tuned);
$dt_next_tuning = $dt_last_tuned->add(new DateInterval('P3M'));
$dt_now = new DateTimeImmutable();
$dt_tuning_upcoming = $dt_next_tuning->sub(new DateInterval('P1M'));
if( $dt_now > $dt_next_tuning) {
return 'late';
}
if( $dt_now > $dt_tuning_upcoming) {
return 'upcoming';
}
You can also use these DateTime objects in your MySQL queries, by building the query and passing through something like $dt_next_tuning->format('Y-m-d H:i:s'); as needed.
Given your table structure, however, it may be easier to just get all the relevant records and process them. It's a little difficult to tell exactly how the pieces fit together, but generally speaking MySQL shouldn't be used for "processing" stuff.

How could I echo a random database field once a week using php and mySQL?

Google hasn't been much help sadly. I have some pseudo code below to give you an idea of what I'd like to achieve:
if ($time == one week) {
$result = mysql_query("SELECT * FROM table RANDOMLY,$connection");
echo $result[0];
}
I know I should be using mysqli, but I'm augumenting an existing (ageing) system. I'll be utilising mysqli in future, so if you could give me the solution using mysql that would be great!
I don't think it can be done with a single statement.
My best guess would be to use mysql_list_tables, select a random entry from that list and continue from there on.
Perhaps generating a random number between 1 and the value of SELECT Count(ID) from table. Then you have the index of the value you wish to output, you can simply run a SELECT statement for it; and output! :)
if ($time == one week) {
$result = mysql_query("SELECT * FROM table RANDOMLY,$connection");
echo $result[0];
}
Try this:
$weekNumber = date("W");
$result = mysqli_query("SELECT * FROM table RANDOMLY WHERE weeknumber = '\"$weekNumber\"', $connection");
echo $result[0];
}
Of course you’ll need a column in your table called weeknumber with 1 through 52 setup ahead of time.
As others pointed out you shouldn’t use mysql_* anything. I changed it to a mysqli_query.

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