Monday 9 September 2019

Why does a less than or more than comparison in PHP of two strings in the date format of "YYYY-MM-DD" work even though they are strings?



I am working on a section of PHP code for a project that compares a date in the YYYY-MM-DD format to the current date to see if it is less than the current date. At different points in the code two different methods were used for making this comparison. The first used get_timestamp() on the dates and ran the comparison off of the timestamps. In another place it just compared the string of the date to the output from date("Y-m-d"). My expectation was that the comparison of two date strings would not provide a correct response. However, when I set up several test cases I got the output expected. I reviewed two parts of the PHP manual for insight and I am still confused as to why the comparison works without conversion to a timestamp.



The comparison operators section of the PHP manual states that the strings are either being converted to numbers and a numerical comparison is then made or that it makes something called a lexical comparison. I couldn't find anything further on lexical comparisons, but when I read about string conversion to numbers and tried the examples using date strings I get the same numerical output for each date string I try.




Can someone help me understand why a greater than or less than comparison of two date strings works (or at least appears to be working)? What am I missing?



As a follow up, if it really does work, I am assuming it is a better practice to convert the date to a timestamp and do the comparison based on the timestamp. Which is the better function to use for converting a date to a timestamp: get_timestamp() or strtotime()?



Sample code of less than / more than comparison of two YYYY-MM-DD strings:



if ("2013-06-27" < "2013-06-28") { echo "less"; } // Output: less
if ("2013-06-27" > "2013-06-28") { echo "more"; } // Output: (none)

if ("2013-06-29" < "2013-06-28") { echo "less"; } // Output: (none)

if ("2013-06-29" > "2013-06-28") { echo "more"; } // Output: more


Sample code testing numeric value of a converted YYYY-MM-DD string



$foo = 1 + "2013-06-27";
echo "\$foo==$foo"; // Output: $foo = 2014
$foo = 1 + "2013-06-28";
echo "\$foo==$foo"; // Output: $foo = 2014
$foo = 1 + "2013-06-29";

echo "\$foo==$foo"; // Output: $foo = 2014

Answer



When you compare a string this way, it will go from left to right, and compare each character in the given string to see if they are different, until it finds a difference, then it will decide which string is bigger by comparing the ASCII value of this last character. Coincidentally, since you are using only numbers, the highest numbers are also higher on the ASCII table.



This solution will work as long as you use only numbers in your comparisons, and that each string has the same number of characters



Also note that this works only since you are using the YYYY-MM-DD format, if you used another format it would not work.


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...