Date comparison in PHP behaving unpredictably - php

I have a date string like this: 2010-9-30 in my $date_string variable.
When I compare strings like this:
if ( date( 'Y-m-d', strtotime( "+20 days", $date_string ) ) )
{
// it returns true for all dates
}
The comparison is true for all dates, even from yesterday, which isn't 20 days ago. Any idea why that might be happening?
Thanks!

You are not making any comparisons between dates. Instead, you are testing whether you can successfully convert the date supplied as the second parameter to strtotime() into a valid date. That result is always true, because every date has a valid date 20 days in the future.
In other words, if date() returns a truthy value your condition is TRUE. It will always return a truthy value unless you pass it an invalid timestamp in its second parameter (for example, the 42nd of February)
If you want to compare the output of that date() call to another date string, you will need an additional operand inside your if():
if ('2011-09-02' == date('Y-m-d', strtotime("+20 days", $date_string))) {
}

It's returning the date in the string format of (for example) 2000-01-01, which when converted to boolean is true.
Instead, check for this:
if (time() > strtotime("+20 days", $date_string)) // Returns true if $date_string was in the last 20 days, or is in the future
Obviously, if you want dates more than 20 days old only, just flip the > to a <

Related

Comparing actual date with other date

I have this
$fecha_actual = strtotime('now');
$fechaactual = date("d/m/Y",$fecha_actual);
$fechatope = $fila1['fechatope'];
if($fechatope < $fechaactual) {
echo "Fecha Actual: $fechaactual y Fecha Tope: $fechatope ";
}
The result I obtain:
Fecha Actual: 03/10/2018 y Fecha Tope: 03/02/2019
Why enter on the if when $fechatope is bigger than $fechaactual?
I dont understand...
Try to compare them with
strtotime($fechatope) < strtotime($fechaactual)
This way it just compares integers, less error chances.
In PHP, the date function returns a string. So your variable $fechaactual is the string
"03/10/2018"
Now I'm guessing your variable $fechatope is the string
"03/02/2019"
If you do a string comparison, $fechaactual is greater!
This is why most programmers these days do not use country-specific date formats. If you are going to compare strings, use the international date format, ISO 8601, and not a country's specific format. ISO 8601 allows sorting on strings, because it is YYYY-MM-DD. Formats that are day-first or month-first are bad for programming. (End of rant! :) )
Alternatively, you can compare date objects themselves, or reduce each date to an epoch time.
Dates are hard.
Try this
$fecha_actual = strtotime('now');
$fechaactual = date("d/m/Y",$fecha_actual);
$fechatope = date("d/m/Y",strtotime($fila1['fechatope']));
if($fechatope < $fechaactual) {
echo "Fecha Actual: $fechaactual y Fecha Tope: $fechatope ";
}
date() returns a string. So you are comparing if a string is less than another string (I'm assuming the type of the second parameter since we don't see it).
There are many special rules when it comes to comparison of strings with < and > in PHP. It will compare strings based upon alphabetical order. If a string starts with a number that number will use in the comparison and so on.
No matter what, this is most likely not what you expect.
Either, you could turn both times into timestamps which are both numerical and can be compared as in your code. Or you could turn the strings into DateTime objects and use the DateTime::diff function or boolean operators like <, > and == to compare the dates.
Assuming you have a string 03/02/2019 and you want to compare it with current time:
$fechaactual = new DateTime(); // current date and time
$fechatope = DateTime::createFromFormat("m/d/Y|", "03/02/2019"); // 2019-03-02 00:00:00
var_dump($fechaactual < $fechatope); // true
var_dump($fechaactual == $fechatope); // false (warning: dont use ===)
var_dump($fechaactual > $fechatope); // false
This looks far more complicated solution that others but it is the most versatile. It leaves no ambiguity as long as you know the date format(s) involved.
This is because in your given example, by comparison your Fecha Tope IS smaller than your Fecha Actual.
WHY?
Because of your date format. Imagine the PHP code working out whether one date is bigger or smaller than the other. It does so by calculating it like an integer.
So let's convert our dates to integers:
Fecha Actual = 03102018
Fecha Tope = 03022019
Now because your date is formatted as day, month, year - it doesn't matter much if there is a year difference, because that will be the smallest unit in our integer value. Whereas a difference in a day will result in the largest unit changes.
If you reorganise your code, and from now on use "Y-m-d" then you will avoid this problem when comparing dates.
Since date() returns a string, you will have to format it. You will also need to abide by the programmatical standards for time, which is Y-m-d, and not your country-specific standards.
Assuming you are fetching another date (the one you compare it with) from the database, you will have to format that string to time as well, using the strtotime() function.
Example:
$dateExample=date('d/m/Y'); // your date() string
$format = "d/m/Y"; // current string format to change.
$timedate = DateTime::createFromFormat($format, $dateExample); //creates the format and changes the string to a dateTime object.
$dateExample = $timedate->format('Y-m-d'); //perform the format, changing the standard to Y-m-d format.
$anotherDateFromDataBase = $row['dateColumn']; //date variable fetched from the database
$anotherDateFromDataBase = strtotime($anotherDateFromDataBase); //converts the string to time
You can now compare the two dates.
if($anotherDateFromDataBase < $dateExample) {
//do something
}

PHP is today between these dates (exclude year)

I'm trying to do a simple if echo statement.
<?php if (time("mm-dd") > strtotime("11-01") && time("mm-dd") < strtotime("02-28"))echo 'stuff' ?>
Basically I want to echo something if today is either Nov, Dec, Jan, Feb. The code works if I use time() and the full year but I'd like to just compare the month, day. I think I have some silly syntax error that I just can't figure out. This code snippet is placed in the <head> of my html if that makes a difference. Little help. Thanks.
This is what I ended up with. Thanks!
<?php if ($today > '12-16' || $today < '01-08') echo 'yes' ?>
with $today = date("m-d")
Use the date function instead of time.
Switch && to ||. No m-d date string will ever be both greater than 11-01 and less than 02-28.
You probably want to use an inclusive comparison operator with November 1 and an exclusive one against March 1 to account for leap years.
Instead of calling date() twice, why not assign the result to a variable?
Here it is all together:
$today = date('m-d');
if ($today >= '11-01' || $today < '03-01') { ... }
Consider using date checking the month only:
$month = (int) date("m");
$isMonthCorrect = $month === 11 || $month === 12 || $month === 1 || $month === 2;
Note the importance of (int). Integer comparisons are more reliable than string comparisons, even if they behave similarly.
Or if you want to check between two dates, to optimize performance, you should evaluate the dates into timestamps before putting them in code.
For example, you can use some websites for converting Unix timestamps. (Not gonna advertise any here, but you can search "Unix timestamp converter) You can also use php -r to get quick output:
php -r 'echo strtotime("2016-11-01 00:00:00");'
php -r 'echo strtotime("2017-02-01 00:00:00");'
Then you can use them like this:
$minimum = 1477958400; // from first command line
$maximum = 1485907200; // from second command line
$isInPeriod = $minimum <= time() && time() <= $maximum;
Keep in mind:
time() always returns the current Unix timestamp, i.e. number of seconds since the Unix Epoch. Use strtotime for converting a string to time, and use date() to convert a timestamp to a string in a given format.
Unix timestamp is always absolute. You can't convert a "month" into a Unix timestamp. You can only obtain the current Unix timestamp with time(), or get specific data from the timestamp using date().
References:
strtotime
time
date

php strtotime() values not working as expected

this code keeps telling me that $lasUpdate is always greater than $yesterday no matter the change i make to $yesterday result is (12/31/14 is greater than 01/19/15 no update needed). i feel like i'm missing something simple thank you in advance it is greatly appreciated.
$result['MAX(Date)']='12/31/14';
$lastUpdate = date('m/d/y', strtotime($result['MAX(Date)']));
$yesterday = date('m/d/y', strtotime('-1 day'));
if($lastUpdate<$yesterday){echo $lastUpdate.'is less '.$yesterday.'<br>'.'update needed';}
if($lastUpdate>=$yesterday){echo $lastUpdate.'is greater than '.$yesterday.'<br>'.'no update needed';
You have fallen victim to PHP type juggling with strings. A date function has a return value of a string. You cannot compare dates in their string format since PHP will juggle strings into integers in the context of a comparison. The only exception is if the string is a valid number. In essence, you are doing:
if ('12/31/14' < '01/19/15') { ... }
if ('12/31/14' >= '01/19/15') { ... }
Which PHP type juggles to:
if (12 < 1) { ... }
if (12 >= 1) { ... }
And returns false on the first instance, and true on the second instance.
Your solution is to not wrap date around the strtotime functions, and just use the returned timestamps from the strtotime functions themselves to compare UNIX timestamps directly:
$lastUpdate = strtotime($result['MAX(Date)']);
$yesterday = strtotime('-1 day');
You will however want to use date when you do the echo back to the user so they have a meaningful date string to work with.
Try something like this:
$lastUpdate = strtotime($result['MAX(Date)']);
$yesterday = strtotime('-1 day');
if ($lastUpdate < $yesterday) { /* do Something */ }
12/31/14 is greater than 01/19/15
Because 1 is greater than 0. If you want to compare dates that way you will need to store them in a different format (from most to least significant digit), for example Ymd.
Or store the timestamps you are making in the different variables and compare them.

How to convert date into integer number in php?

I have an mysql database with a date column and i am using datatype datetime.
But now i want change my datatype from datetime to long integer
I would like to know how to convert date to any integer value.
Let say i have a date
i.e 2012-03-27 18:47:00
so I was wondering if it's possible to convert into any integer number like 131221154
Use strtotime function of PHP.
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
echo strtotime('2012-03-27 18:47:00'); //--> which results to 1332866820
And to make it back again, just use the date function of PHP:
$long = strtotime('2012-03-27 18:47:00'); //--> which results to 1332866820
echo date('Y-m-d H:i:s', $long);
check this
<?php
$timestamp = strtotime('1st January 2004'); //1072915200
// this prints the year in a two digit format
// however, as this would start with a "0", it
// only prints "4"
echo idate('y', $timestamp);
?>

Adding leading zeroes to a string date in PHP

I have a string "date" which can be DD.MM.YYYY or D.M.YYYY (with or without leading zeros), it depends what a user types.
Then I use it in a condition to send another email when the day is today.
if($_POST["date"]== date("d.m.Y")){
$headers.="Bcc: another#mail.cz\r\n";
}
The problem is that the mail is send when the date format DD.MM.YYYY (with leading zeros) only.
My proposed solution
As I'm not very good in PHP, I only know the solution theoretically but not how to write the code - I would spend a week trying to figure it out on my own.
What's in my mind is dividing the date into three parts (day, month, year), then checking the first two parts if there's just one digit and adding leading zeros if it's the case. I don't know how to implement that to the condition above, though. I have read a few topics about how to do this, but they were a bit more different than my case is.
You should equalize to same format d.m.Y and you can do this with strtotime and date function:
$post_date = date("d.m.Y", strtotime($_POST["date"]));
if($post_date == date("d.m.Y")){
$headers.="Bcc: another#mail.cz\r\n";
}
I changed date to $post_date for more clear. I'll try to explain difference with outputs
echo $_POST["date"]; // lets say: 8.7.2013
echo date("d.m.Y"); // 09.09.2013 > it's current day
strtotime($_POST["date"]); // 1373230800 > it's given date with unix time
$post_date = date("d.m.Y", strtotime($_POST["date"])); // 08.07.2013 > it's given date as right format
If you use date function without param, it returns as current date.
Otherwise if you use with param like date('d.m.Y', strtotime('given_date'));, it returns as given date.
$post_date = date("d.m.Y", strtotime($_POST["date"]));
At first, we converted your date string to unix with strtotime then equalized and converted format that you used in if clause.
first set date format with leading Zero
$postdate = strtotime('DD.MM.YY', $_POST['date']);
and also matching date will be in same format
$matching_date = date('DD.MM.YY', strtotime('whatever the date'));
then
if ( $postdate === $matching_date )
{
// send mail
}
Why don't you just check the length of the _POST (it can be either 8 or 10)
if (strlen($_POST["date"]) == 10) {
$headers.="Bcc: another#mail.cz\r\n";
}

Categories