How to debug my PHP validation function? - php

I am creating a web form for my work which is being validated using PHP. However, when I test the page I keep getting all of my error messages returned without the form being submitted properly when valid information is inputted. The following is a small section of the code (including the HTML sections).
<?php
$date =""
$dateerror = ""
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["date"])) {
$dateerror = "Date is required";
} else {
$date = test_input($_POST["date"]);
$array = explode("/", $date);
$day = $array[1];
$month = $array[0];
$year = $array[2];
if (!checkdate($month, $day, $year)) {
$dateerror = "Date mustbe in M/D/Y format";
} else {
date_default_timezone_set("America/Anchorage");
$today = strtotime("now");
if (strtotime($date)>=$today) {
$date = test_input($_POST["date"]);
} else {
$dateerror = "Date is before present day";
}
}
}
<input type="text" size="9" name="date" id="date" required title="Please enter current date"><?php echo $dateerror; ?><br>
Again, the PHP code just returns "Date is before present day" even when the date is the current date.

If you want to validate a date in PHP, the best way to do it is to use the DateTime class, and specifically the createFromFormat method.
This call will create a DateTime object set to the specified date in the given format, or false if it was an invalid date.
So for example:
<?php
$input = "05/08/2015";
$test = DateTime::createFromFormat('d/m/Y', $input);
if (!$test) {
print "You entered an invalid date";
die;
}
$now = new DateTime();
if ($test < $now) {
print "Date is before present.";
die;
}
?>
Simple as that. There's no need for regex, or for exploding the input, etc; just a single simple test. And you can also then use the $test variable to process the date as well once you've determined that it's valid, since it's a standard DateTime object.
[EDIT] I've added a bit in the code to deal with using the DateTime class to handle date comparisons, to give the 'before present' error.
The important point here is that if you have a DateTime object, you need to compare it with another DateTime object; the older strtotime() produces a different type of date resource to DateTime, and you can't use them together (at least not without converting between them all the time).

The solution: use date("M/D/Y"):
$today = strtotime(date("M/D/Y")); // 1432958400
$date = strtotime($_POST["date"]); // user input. 05-30-2015 will yield 1432958400
// the rest of your logic here
Here's the code specific solution:
<?php
$date =""
$dateerror = ""
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["date"])) {
$dateerror = "Date is required";
} else {
$date = test_input($_POST["date"]);
$array = explode("/", $date);
$day = $array[1];
$month = $array[0];
$year = $array[2];
if (!checkdate($month, $day, $year)) {
$dateerror = "Date mustbe in M/D/Y format";
} else {
date_default_timezone_set("America/Anchorage");
$today = strtotime(date("M/D/Y"));
if (strtotime($date)>=$today) {
$date = test_input($_POST["date"]);
} else {
$dateerror = "Date is before present day";
}
}
}
<input type="text" size="9" name="date" id="date" required title="Please enter current date"><?php echo $dateerror; ?><br>

Related

How to check if 2 different format date strings is a valid dates?

I need to check if 2 different format date strings is a valid dates. The formats are: YYYY-MM-DD and YYYY.MM.DD. I found just only one date string format validation, like so:
function validateDate($date)
{
$d = DateTime::createFromFormat('Y-m-d', $date);
return $d && $d->format('Y-m-d') == $date;
}
function was copied from this answer or php.net
But how about two date formats validation? How to solve it? Thanks for any help
Try the following for both:
$date="2017-09-11";
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
echo true;
} else {
echo false;
}
$date="2017.10.22";
if (preg_match("/^[0-9]{4}.(0[1-9]|1[0-2]).(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
echo true;
} else {
echo false;
}
It uses regex to check if the format is valid or not.
OR
$date="2017-09-11";
$dt = DateTime::createFromFormat("Y-m-d", $date);
echo $dt !== false && !array_sum($dt->getLastErrors());
$date="2017.10.22";
$dt = DateTime::createFromFormat("Y.m.d", $date);
echo $dt !== false && !array_sum($dt->getLastErrors());
It uses DateTime to check the date against both formats.
Edit: While both are decent solutions, benchmarks show that in this case, preg_match is considerably faster than DateTime. https://3v4l.org/H8C73
Copy the original function, where you specify format as 2nd parameter, and then run function twice; as already mentioned in the comments.
function validateDate($date, $format = 'Y-m-d H:i:s')
{
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}
$isValid = validDate($date, 'Y-m-d') || validDate($date, 'Y.m.d');
function was copied from this answer or php.net

Get time difference & User Information using php

Please, i need to get the time difference between a particular time and the current time. ie. I want to track users who submit an assignment late. the deadline time is 10:00AM everyday.I have surf,but all the solution i am seeing does not seems to work. see below:
<?php
$d1 = new DateTime(date('Y-m-d 10:00:00'));//Deadline time
$d2 = new DateTime(date('Y-m-d H:i:s'));//Submission time
$interval = $d1->diff($d2);
$c = $interval->minute;
if($c>0){
echo "submitted late";}else{ echo "Submitted on time";}
?>
Regarding the first point, your code doesn't work because $interval->minute is always positive. So you should simply compare two dates.
Use the following code to achieve it:
$d1 = new \DateTime(date('Y-m-d 10:00:00'));//Deadline time
$d2 = new \DateTime(date('Y-m-d H:i:s'));//Submission time
if($d1 < $d2) {
echo "submitted late";
} else {
echo "Submitted on time";
}
$deadline = date('10:00:00');
$now = date('H:i:s');
if($now > $deadline){
echo "submitted late";
} else {
echo "Submitted on time";
}
as simple as that

How to validate date using PHP?

I have small problem with date validation. It works if it only validates a day, not the whole date.
If, today is 21.07.2015, validation enables dates before the 21st of each month/each year. It should accept only dates starting from today.
Code is here:
if (empty ($_POST['data'])) {
$data_error = "You need to type a date";
++$error_counter;
} elseif ($_POST['data'] < date("d.m.Y")) {
$data_error = "You have chosen incorrect date";
++$error_counter;
} else {
$data = $_POST['data'];
}
You can compare by strtotime()
if (empty ($_POST['data'])) {
$data_error = "You need to type a date";
++$error_counter;
} elseif (strtotime($_POST['data']) < strtotime(date("d.m.Y"))) {
$data_error = "You have chosen incorrect date";
++$error_counter;
} else {
$data = $_POST['data'];
}

PHP compare a given datetime with current datetime

I have a problem comparing a customized php datetime with current datetime, the code is below:
$requestDate = new DateTime("2014-05-28 11:14:00");
$nowDate = new DateTime();
$aklTimeZone = new DateTimeZone("Pacific/Auckland");
$requestDate->setTimezone($aklTimeZone);
$nowDate->setTimezone($aklTimeZone);
echo $nowDate->format("Y-m-d H:i:s");
if ($requestDate > $nowDate) {
echo '1';
} else if($requestDate == $nowDate){
echo '0';
} else{
echo "-1";
}
The printed result is:
2014-05-28 12:21:31
1
The $requestDate is supposed to be less than the $nowDate, how come it is greater here?
Thank you

Validating timezone 'name' coming in from different site?

i've got users coming in from a different site and i'm getting that site to send across their timezone in a standard 'tz' format
Antarctica/Casey Antarctica/Davis
Antarctica/DumontDUrville Antarctica/Macquarie
Antarctica/Mawson Antarctica/McMurdo
How do i verify that this 'string' coming in is a VALID timezone entry?
this is what i'm doing
$script_tz = date_default_timezone_get();
if(!date_default_timezone_set($specifiedTimeZone))
{
date_default_timezone_set($script_tz);
$errormessage = "Invalid TimeZone";
return;
}
date_default_timezone_set($script_tz);
but i dont like it - seems kludgy.
testing it out:
Test1
$test1 = 'America/New_York';
$test2 = 'junk';
$start = microtime(true);
for($i=1;$i<10000;$i++)
{
if (in_array($test1, DateTimeZone::listIdentifiers())) {}else {}
if (in_array($test2, DateTimeZone::listIdentifiers())) {}else {}
}
$end = microtime(true);
echo $end-$start;
?>
9.7208099365234
Test2
<?php
$test1 = 'America/New_York';
$test2 = 'junk';
error_reporting(0);
$start = microtime(true);
for($i=1;$i<10000;$i++)
{
$script_tz = date_default_timezone_get();
if(!date_default_timezone_set($test1))
{
date_default_timezone_set($script_tz);
}
else
date_default_timezone_set($script_tz);
$script_tz = date_default_timezone_get();
if(!date_default_timezone_set($test2))
{
date_default_timezone_set($script_tz);
}
else
date_default_timezone_set($script_tz);
}
$end = microtime(true);
echo $end-$start;
?>
0.25762510299683
use DateTimeZone::listIdentifers()
if (in_array($timezone, DateTimeZone::listIdentifiers())) {
echo "valid";
}
else {
echo "invalid";
}
Validate against the tz database. There's http://code.google.com/p/tzdata/, that claims to provide the tz database in PHP format (whatever this means).
Check out this: How to check is timezone identifier valid from code?
Report different approaches to solve your problem.
There is a helper: timezone_identifiers_list() will return an array of strings of timezones. then you can use something like in_array to validate it.
if (in_array($timezone, timezone_identifiers_list())) {
// valid
}
You could take the list of supported timezones, save it in a file and compare what you're getting to the list:
http://php.net/manual/en/timezones.php

Categories