timezone and time() issue, time now is less than time before - php

I am using wordpress where the defualt timezone is UTC, though I do not understand why this would make a difference because it is the same person that wants to update something on the website, and the time compared is for that person, in this case me.
So, I want to update my password, and when that happens a new datetime value is inserted in the appropriate table, and when I click the link in the email link that I receive, the page I go to makes a new time like so:
$time_now = date('Y-m-d H:i:s');
$time_now = strtotime($time_now);
And before that I pull the appropriate value from the table and convert it to time like so:
$time_then = strtotime($time_then);
So even though it is ME doing all this from the same computer, I get a result where $time_then is BIGGER than $time_now.
The time seems to be off for like 2 hours, so I can add 2 hours to $time_now, but would that work the way it should for all people, regardless of their country?
And why is $time_then bigger than $time_now anyway?
UPDATE:
Just to make it clear, the time I insert into the DB is CORRECT, while the time I get with php on the page is wrong ( 1 hour less in my case ).
UPDATE 2: code
foreach ($q as $key => $value) {
$time_then = $value->req_date;
$e = $value->email;
}
echo 'Time then normal: '.$time_then.'<br>';
$time_then = strtotime($time_then);
// check how much time has elapsed
$time_now = date('Y-m-d H:i:s');
echo 'Time now normal: '.$time_now.'<br>';
$time_now = strtotime($time_now);
echo 'Time then: '.$time_then.'<br>';
// echo 'Time now: '.$time_now.'<br>';
$time_now = time();
echo 'Time now: '.$time_now.'<br>';
if ($time_now > $time_then) {
echo 'Good <br>';
} else {
echo 'Abnormal <br>';
}
So after I go to the link provided in the email ( after the req_date has been inserted into the DB ), I get for example the following shown on the page:
Time then normal: 2014-11-07 11:11:23
Time now normal: 2014-11-07 10:11:38
Time then: 1415358683
Time now: 1415355098
Abnormal

So after I go to the link provided in the email ( after the req_date has been inserted into the DB ), I get for example the following shown on the page:
$time_now = date('Y/m/d H:i:s');
$time_now = strtotime($time_now);

Related

new \DateTime() gives the same value for multiple requests

I have used the following piece of code in some APIs to limit the request
sleep(1);
// date_value_from_db is taken from DB, question time as example
$date_value_from_db = '2022-12-31 11:18:00Z';
$lastCreatedAt = new DateTime($date_value_from_db);
$now = new \DateTime();
#echo $now->format('Y-m-d H:i:s');
$timeElapsedInSecs = $now->getTimestamp() - $lastCreatedAt->getTimestamp();
// Only execute if the time difference is more than 60 secs
if ($timeElapsedInSecs < 60) {
// throw Exception
}
// Proceed further
If you call this API in a loop, $now->format('Y-m-d H:i:s') returns the same value 3-4 times in a row, after that, it shows the correct current time. and so on. For example echo $now->format('Y-m-d H:i:s') in the above code looks like this:
2022-12-30 11:30:25
2022-12-30 11:30:25
2022-12-30 11:30:25
2022-12-30 11:31:32
2022-12-30 11:31:32
...
Also, the $timeElapsedInSecs value is also the same
Ideally, $now should give the current time for each call. But it's not happening.
Do you guys see any issues with the above code?
I created a file name testdt.php on my local system like this:
<?php
$now = new \DateTime();
echo $now->format('Y-m-d H:i:s')."\n";
When executing this script 100 time (I am on Windows) using:
for /L %f in (1,1,100) do #curl "http://localhost/test/testdt.php"
I do see the returned value change.
When you need more change, you should change 'Y-m-d H:i:s' to 'Y-m-d H:i:s.v', this will add milli-seconds

Carbon PHP equal or greater than not returning true

I'm trying to do a comparison between date & times in Carbon PHP 2. For context, my server is in Europe/London timezone, and a user has the functionality to set their own timezone, thus my $timezone variable. My Laravel 8 project default timezone config is Europe/London too.
When a user provides a start time, I store the date & time as a date field in my DB, but obviously the day, month and year would always be wrong at the point my code runs, thus why we override these with the current day.
Still though, you can see from my output that their time is greater than the start time, but my if statement never runs, why?
$timezone = 'Asia/Tokyo';
$startTime = Carbon::parse('2022-08-01 05:00:00');
$theirTime = Carbon::parse(Carbon::now())->setTimezone($timezone);
$ourTime = Carbon::parse($theirTime)->setTimezone('Europe/London');
$startTime = $startTime->day($theirTime->day);
$startTime = $startTime->month($theirTime->month);
$startTime = $startTime->year($theirTime->year);
echo "their time: $theirTime ----- start: $startTime";
if ($theirTime >= $startTime) {
echo 'run now';
} else {
echo 'do not run';
}
output is:
their time: 2022-08-05 05:16:27 ----- start: 2022-08-05 05:00:00do not run
05:16:27 is greater than 05:00:00 so should output run now, what am I missing?
You can use carbon gte() method
if ($theirTime->gte($startTime)) {
echo 'run now';
} else {
echo 'do not run';
}
as for why it says "do not run", it is because "2022-08-05 05:16:27 GMT+1" comes before "2022-08-05 05:00:00 GMT" and carbon carbon converts itself to integer (unix timestamp) in the comparisation.
I cant give you a complete example because you did not define what $timezone is in your question.
If you want to compare the times as strings directly (and have total faith in your control of timezones you can
if ($theirTime->format('H:i:s') >= $startTime->format('H:i:s')) {
echo 'run now';
} else {
echo 'do not run';
}
Ideally you would run the server in UTC. When the user enters Wake me up at 6am you need to know 6am in what timezone, so need to store the timezone with the 6am or with that user's profile - whatever makes more sense in your application. But it would be a problem to search the database for each user's wakeup time in their own timezone so for activities like this, convert the time to UTC before storing it.
Then if the user wanted waking at 6am, this might be 18:00 utc but that would not matter. When the 'wakeup' time is the same as the server's current time, wake the user up and tell them "this is your $wakeup)->tz($user->timezone) wakeup".
Regarding your specific situation, you want to know if now() in Tokyo is greater than the time on the DB record, however you can only look at the H:m in the stored value;
$theirTime = Carbon\Carbon::parse('2022-03-01 05:00'); // get this from DB
// our reference point
$current = now()->tz('Asia/Tokyo');
$target = now()->tz('Asia/Tokyo');
$target->hour = $theirTime->hour;
$target->minute = $theirTime->minute;
$target->second = 0;
if($current->gte($target)) {
echo 'overdue';
} else {
echo 'Not due';
}

PHP date() adds an hour to return value

I am trying to display the length of time a user has been logged in. I have it working except for once thing. The hours part of the time starts at 1 and not 0.
Here is the PHP code:
//Set the local timezone to GMT
date_default_timezone_set('Europe/London');
//Fetch the timestamp for when user logged in
$loggedins = $conn->query ("SELECT Last_Activity FROM students WHERE Full_Name = '$name'");
$loggedinr = $loggedins->fetch_assoc();
$dateloggedin = strtotime($loggedinr['Last_Activity']);
//Separate the time from the above
$timelogin = date("h:i:s", $dateloggedin);
$timenow = date("h:i:s");
//Work out the time spent logged in
$sessionlength = strtotime($timenow)-strtotime($timelogin);
$sessionlength = date("H:i:s", $sessionlength);
** The Last_Activity column in the database contains: 2020-07-08 10:07:58
Here is the HTML:
<p style="line-height: 40px">Session length: <b><?= $sessionlength?></b></p>
This is what the page displays after being logged in for 13mins:
Session length: 01:13:44
The following amendment shows the correct time (00:13:44)
$sessionlength = date("H:i:s", $sessionlength-3600);
Why does it add an hour? Any constructive help would be appreciated.
I cannot figure out why it's adding an hour, i think the assumption of Siobham makes the most sense, I tried setting the timezone to simply "Europe" and its printing the correct time, but if i add Paris it adds an hour.
Here is what seems to be a more reliable solution
date_default_timezone_set('Europe/London');
$datetime1 = new DateTime('2020-07-08 10:07:58');//start time
$datetime2 = new DateTime($timenow);//end time
$interval = $datetime1->diff($datetime2);
echo $interval->format('%H:%I:%S');

How to make email link expire after X minutes in php?

I am working on email link expire after some X minutes where X denotes some random date_time. so my motive is to expire the the link after some time what ever I set the date_time in side the $expire_date.
So I just created dummy code myself just in order to sure my code works or not.
$currentDateTime = new \DateTime();
$currentDateTime-> setTimezone(new \DateTimeZone('Asia/kolkata'));
$now = $currentDateTime-> format(' h:iA j-M-Y ');
$expire_date = "02:59PM 26-Mar-2019";
if($now > $expire_date)
{
echo " link is expired";
}
else{
echo " link still alive ";
}
I guess I am missing something in the above code, somehow the above code isn't working if anyone would point out the right direction or some better implementation it would be great.
You are comparing the times as strings. This does not work, as your first formatted string has a leading space.
Instead, try either removing the whitespace, or better, compare the times as DateTime objects:
$timezone = new \DateTimeZone('Asia/kolkata');
// Create the current DateTime object
$currentDateTime = new \DateTime();
$currentDateTime-> setTimezone($timezone);
// Create the given DateTime object
$expire_date = "02:59PM 26-Mar-2019";
$expireDateTime = \DateTime::createFromFormat($expire_date, 'h:iA j-M-Y');
// Compare the objects
if($currentDateTime > $expireDateTime)
{
echo " link is expired";
}
else{
echo " link still alive ";
}
If you want to compare dates in PHP, your best bet is to use UNIX time stamps. A UNIX time stamp is the number of seconds since the UNIX epoch (00:00:00 Thursday, 1 January 1970).
time() will return the current UNIX time stamp.
strtotime() will convert a date string into a UNIX time stamp.
So replacing these two lines:
$now = $currentDateTime-> format(' h:iA j-M-Y ');
$expire_date = "02:59PM 26-Mar-2019";
With these:
$now = time();
$expire_date = strtotime("02:59PM 26-Mar-2019");
Should solve your problem.
You are comparing date strings which will not work. You have to parse the string to a datetime object or timestamp before you can compare these values.
For example, using timestamps:
$expire_date = "02:59PM 26-Mar-2019";
if (time() > strtotime($expire_date)) {
echo "link is expired";
} else {
echo "link still alive ";
}
All you have to do is use strtotime function and add inside date function and here you can specify day, hour, minutes, seconds as a perimeter. This way you can set time manually by adding +5 minutes or so on..
date_default_timezone_set("Asia/Kolkata"); // set time_zone according to your location
$created = "2020-08-14 17:52"; // time when link is created
$expire_date = date('Y-m-d H:i',strtotime('+1 minutes',strtotime($created)));
//+1 day = adds 1 day
//+1 hour = adds 1 hour
//+10 minutes = adds 10 minutes
//+10 seconds = adds 10 seconds
//To sub-tract time its the same except a - is used instead of a +
$now = date("Y-m-d H:i:s"); //current time
if ($now>$expire_date) { //if current time is greater then created time
echo " Your link is expired";
}
else //still has a time
{
echo " link is still alive";
}

Comparing DateTime?

I've been doing a good amount of research with this, and used a few codes to get to know how to make this work, but nothing has worked the way I wanted it to, or hasn't worked at all.
The code is:
<?php
$time1 = $user['last_active'];
$time2 = "+5 minutes";
if (strtotime($time1) > strtotime($time2)) {
echo "Online!";
}else{
echo "Offline!";
}
?>
It is supposed to compare the two variables, and find out if the last active variable is greater or less than 5 minutes, and if it is greater, appear offline. I do not know what's wrong as the NOW() updates on each page and stops if the user is not logged in. Any suggestions or help? Thanks.
The $time1 variable is coming from a fetched array that gets the ['last_active'] information that updates on each page.
I fixed my code, but it still doesn't work right, however, I think I have managed to get further than I was..
<?php
$first = new DateTime();
$second = new DateTime($user['last_active']);
$diff = $first->diff( $second );
$diff->format( '%H:%I:%S' );
if($diff->format( '%H:%I:%S' ) > (strtotime("5 minutes"))){
echo "Offline";
}else{
echo "Online";
}
?>
What can I do at this point?
Nobody pointed out that you actually have a bug. The "current time" will never be greater than "the current time +5 minutes"
Your first code sample will work right if you instead use "-5 minutes" as the "online threshold."
Also, comparing a timestamp without date to the output of strtotime() as you do in the second code is not a proper comparison. It has two problems:
Each time a new day comes around, the same time value will be repeated.
The output of strtotime is an integer representing seconds-since-epoch; the output of format() is a textual representation of hours:minutes:seconds within the current date.
As for your question how to calculate time between 2 dates / time, please view the solution on the following posts, that should give you enough information! (duplicate ? )
Calculate elapsed time in php
And here
How to get time difference in minutes in PHP
EDIT AS YOU PLEASE
<?
$first = new DateTime(); // this would hold your [last active]
//$first->modify("-6 minutes");
$second = new DateTime("NOW");
$difference = $second->diff( $first ); // second diff first
if ($difference->format('%i') > 5) { // comparing minutes only in example ( %i )
echo "The user is AFK";
} else {
echo "user might still be active";
}
?>

Categories