Where date('H') value comes from and what can affect it - php

I have a script that uses an if statemnt based on date('H')
if (date('H') >= 16) { do this}
98% of the time this works correctly.
On some submissions (date('H') > 16) it fails, if statment not fired.
Where does this value come from, is there anything from an individual users PC that can affect it?
I have tried modifying the system clock with no difference, no idea why some of these are failing.

Returns a string formatted according to the given format string using
the given integer timestamp or the current time if no timestamp is
given. In other words, timestamp is optional and defaults to the value
of time().
Well you could check with time() what value is currently handled.
Do to your problem:
Everything that is before 4pm will fail since the condition goes falsey.

date outputs the current server time formatted in the timezone set by date_default_timezone_set. If you're getting unexpected values from it, you may be globally setting the timezone somewhere which changes the output:
date_default_timezone_set('UTC');
echo date('H'); // 15
date_default_timezone_set('Asia/Tokyo');
echo date('H'); // 00

Related

STRTOTIME in php returning blank value

The dataset value is returning blank, no error on logfile.
$edate = trim($_POST['txtedate']); //user inputs date 12-01-2021
$int_effective_date = new DateTime(strtotime($edate));
echo "edate:- ".$edate."<br />";
echo "strtotime_edate:- ".strtotime($edate)."<br />";
echo "dateset:- ".strtotime($int_effective_date->format('Y/m/d'));
Result:
edate:- 2021-01-12
strtotime_edate:- 1610389800
dateset:-
To paraphrase #iainn: I'm not 100% sure why you're changing back and forth between DateTime objects and function calls to strtotime?
However, I can explain the most likely issue with your code...
strtotime
Firstly, let's clarify that 12-01-2021 is in the format (d-m-Y)? Hopefully it is, in which case PHPs strtotime function understands it correctly and produces a Unix timestamp (i.e. seconds passed since start of 1970)...
strtotime("12-01-2021");
// Output: 1610409600
// Notes:
// - Possible slight variations based on locale etc.
// - Lookup: date_default_timezone_set
// - This is with "UTC"
DateTime
You then pass that timestamp to DateTime but neglect to inform DateTime what kind of timestamp it is...
$int_effective_date = new DateTime(strtotime($edate));
// Is the same as...
$int_effective_date = new DateTime(1610409600);
However, DateTime doesn't see your timestamp as incorrect and tries to process it anyway...
In the format: HisYmd
But your input is too short for that so it only matches HisY
Time => 16:10
Year => 9600
Given the lack of data DateTime then fills in the blanks with today (example: 2021-02-05)
Day => 05
Month => 02
Which give you a complete timestamp of: 9600-02-05 16:10:40
strtotime from DateTime
Your next line of code then passes that timestamp back into a strtotime call...
echo "dateset:- ".strtotime($int_effective_date->format('Y/m/d'));
// Is the same as...
echo "dateset:- ".strtotime("9600/02/05");
Now, strtotime will always return something. Which means the first problem is that you're using echo which doesn't output (bool) false.
Try:
var_dump(strtotime("9600/02/05"));
You might ask, why doesn't that happen in the linked code example from #El_Vanja?
Answer
The answer to that, I believe, is that your PHP version is not up to date and anything over the 32 bit date range is going to return (bool) false from strtotime.
To fix this specific problem I suggest you update your PHP version (and OS if you haven't moved to 64 bit!)
However, further to that, I strongly suggest you stick to the DateTime object/class. It saves you from all of these annoying bugs if nothing else...
For reference:
echo strtotime( (new DateTime("#1610409600"))->format("Y-m-d") ); // Output: 1610409600
echo strtotime( (new DateTime("2021-01-12"))->format("Y-m-d") ); // Output: 1610409600

How to set php timezone by offset value in hh:mm, minuts or seconds?

My online application gets users timezone offset in + or - value in minutes. I want to set this value in server.
MySQL / MariaDB accepts timezone values and works perfectly
SET time_zone = "+0:15";
But php only accepts timezone string like this
date_default_timezone_set("Asia/Karachi"); // Works Perfectly
And does not set time in offset value
date_default_timezone_set("+0:15"); // Error
Is there any way to set php time with offset value?
After reading the documentation for the date_default_timezone_set() php function, this seems to be a common issue.
I'm sure there may be alternatives if you choose to use other date functions in php, however, to be able to set the timezone by an offset, you would require a helper function to do this.
I've copied and modified a helper function posted on the php doc page here
function setTimezoneByOffset($offset)
{
$testTimestamp = time();
date_default_timezone_set('UTC');
$testLocaltime = localtime($testTimestamp,true);
$testHour = $testLocaltime['tm_hour'];
$abbrarray = timezone_abbreviations_list();
foreach ($abbrarray as $abbr)
{
//$abbr."<br>";
foreach ($abbr as $city)
{
date_default_timezone_set($city['timezone_id']);
$testLocaltime = localtime($testTimestamp,true);
$hour = $testLocaltime['tm_hour'];
$testOffset = $hour - $testHour;
if($testOffset == $offset)
{
return $city['timezone_id'];
}
}
}
return false;
}
Where the parameter $offset is a string representation of the offset (ie. '+0:15'), which returns the timezone id of the timezone which matches that of your input.
My online application gets users timezone offset in + or - value in minutes.
This is problematic, because a time zone offset is not the same thing as a time zone. Consider that one cannot take the current offset and assume it is the correct offset to apply for any given date and time. Many time zones use more than one offset depending on time of year, and many time zones have had changes to their standard time offsets at different points in history. For more on this, see "Time Zone != Offset" in the timezone tag wiki.
As an example, you might be using a JavaScript function like new Date().getTimezoneOffset(). However, this returns the offset for the Date object returned by new Date() - which is the current date. For me, in the US Pacific time zone, it will return 480 (UTC-8) when run in the winter during standard time, but 420 (UTC-7) when run in the summer during daylight saving time.
Instead, have your front-end call Intl.DateTimeFormat().resolvedOptions().timeZone in JavaScript to return the time zone identifier, which for me returns "America/Los_Angeles". You can pass that to your back-end and use it with PHP.
As a side note, there are no time zones in the world that use or have ever used UTC+0:15. The closest to that would have been UTC+0:20 used in the Netherlands from 1 May 1909 to 16 May 1940. This is already captured in the history of "Europe/Amsterdam".

timestamp from both date & time inputs and compare php

I've been struggling to get an exact answer for this question. There are many that are close to what I'm wanting but seem to still be just off. The application of this is to ensure that a booking can't be made for a past date.
I have a form which has an input for time & another for date. Firstly, I wan't to take both of these inputs & convert them to a timestamp.
This code returns nothing
$time_date = sprintf("%s %s", $pDate, $pTime);
$objDate = DateTime::createFromFormat('H:ia d/m/Y', $time_date);
$stamp = $objDate->getTimestamp();
echo $stamp;
So I've have tried using something like this
$pDate = $_POST['pDate'];
$pTime = $_POST['pTime'];
$full_date = $pDate . ' ' . $pTime;
$timestamp = strtotime($full_date);
echo $timestamp;
But for some reason it is returning an incorrect timestamp. (i've been using an online converter) 02/06/2014 as date & 12:23am as time, is not 1401625380. This according to the converter is Sun, 01 Jun 2014 12:23:00 GMT.
Does someone have working code for returning a timestamp of both time & date inputs?
Secondly I want to compare this timestamp with a specified one & check to see if it is greater than. I've created a timestamp for my timezone with this
$date = new DateTime(null, new DateTimeZone('Pacific/Auckland'));
$cDate = $date->getTimestamp();
echo $cDate;
and will simply have an if statement which compares the two and echos the appropriate message.
I feel as though there are multiple question on here that are ALMOST what I'm wanting to achieve but I can't manage to get them working. Apologies for the near duplicate.
Note: I'm using ajax to post form data (if this could possibly interfere).
Your second code snipped is correct. Assuming it's in datetime format (Y-m-d H:i:s).
From php manual about strtotime():
Each parameter of this function uses the default time zone unless a time zone is specified in that parameter.
Check your PHP default time zone with date_default_timezone_get() function.
To compare two dates, be sure they both are in same time zones.
For datetime inputs I personally use jQuery UI timepicker addon.
you receiving the time and date in string format - so i don't believe the ajax can interfere.
as for your question:
first of all - find out what is the locale timezone of your server. you can do it by this function: date_default_timezone_get.
if the answer doesn't suit you - you can use its "sister": date_default_timezone_set, and change it to whatever value you need (like 'Pacific/Auckland' - see the documentation there). it is also recommended to return it to the original value after you finish your stuff.
i believe fixing your locale timezone will solve your issue.

php date function calculation not working

Hello i am learning php i tried to use the date function to display the current time.
I have an if statement to check the current time whether it is greater than the next hour.
Here is the code
<?
$current_time= date('G:i:s');
$next_time= date('G:i:s',strtotime('+1hour'));
if($current_time > $next_time )
{
echo $current_time." is greater than ".$next_time;
}
?>
At the time of writing this code it was 9:23:39
and the next hour should have been 10:23:39
Surprisingly i got :
9:23:39 is greater than 10:23:39
Am i missing something here.
Please help
Keep in mind you are comparing strings, not numbers. 9 is greater than 1 and therefore returns true.
Either use the DateTime class to do this, or compare the unix timestamps (time() and strtotime('+1hour'))
you could use a integer to work the if statement
$var = date("U",timestamp)
to get the number of Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) thus giving you a number which you can determine which one is greater.

Comparing two date / times to find out if 5 mins has lapsed between the two times php

I need to compare two dates to show an edit link if it is within 5 mins after the post was made, in PHP. If more than 5 minutes have passed, don't show anything.
$answer_post_date = get_the_time("Y-m-d");
$current_date = date("Y-m-d");
$formated_current_date = strtotime($answer_post_date);
$formated_answer_post_date = strtotime($current_date);
At this point I have two values:
1274414400 ($formated_current_date)
1276056000 ($formated_answer_post_date)
I am not sure what to do next to check if the current date/time is > 5 mins from the answer post date.
Any suggestions would be great.
All I really need the answer to be is a Boolean (yes/no) and if yes, display the minuets left to show the link to edit.
You're only handling dates, how are you supposed to know if the difference is 5 minutes?
Anyway, I'd say the majority of the PHP code that uses the default PHP functions is at least somewhat broken. The problem is you, despite a unix timestamp storing the correct point in time something happens, it does not store timezone information. See here.
So, forget using only date and strtotime. Use the datetime extension.
Store in the database the Unix timestamp and the timezone (by timezone I mean e.g. Europe/Lisbon). Then:
$tz = new DateTimeZone($timezone);
$answer_post_date = new DateTime("$timestamp");
$answer_post_date->setTimeZone($tz);
$current_date = new DateTime("now", $tz);
$diff = $current_date->diff($answer_post_date);
if ($diff->format("a") > 0 ||
$diff->format("h") > 0 ||
$diff->format("m") >= 5) {
//more than 5 minutes have passed
}
Of course, for comparing dates, you can always compare the timestamps.
My understanding of what you need to do:
$delta = ($formated_current_date - $formated_answer_post_date) / 60; // in minutes
if ($delta < 5) {
// show $delta
}
EDIT: Like others pointed out, this alone will not fix all of the issues at hand. As I see it, the smallest change to your current code would be to use a date format with higher granularity - such as "Y-m-d H:i:s". This being enough, like others pointed out, is contingent on the post's date being in the same timezone as your system.
I don't see the need to do a round-trip to a string format and back, regardless of how efficient or reliable it is.
date() will default to calling time() which you can call directly and get the current time in seconds as a Unix epoch timestamp (which is what you're trying to end up with in $formated_answer_post_date). You need to look in the WordPress docs to find the equivalent based on the post's value.
Then you can do a simple comparison of seconds. 5 minutes is 300 seconds.
You will still need to check that the code can assume the timezones of both values will be the same.

Categories