I am making a registration form and I'd like to get the birth date of each registered user.
<input class="field" type="date" name="birthday" max="9999-12-31" />
When I was making this, though, I realised that everyone can open the Inspect Element options and put any value they like. This will go to the database and just ruin the experience. I don't want to let this happen, so I am now looking for a way to do the following:
Find a way to check if the date is valid (no matter what the format is, mm/dd/yyyy and dd/mm/yyyy will both get accepted into the database but they will be converted to yyyy-mm-dd before going there)
Make sure the region doesn't matter (like I said, every format will get accepted but I'm a bit worried about the fact that some countries show the input field differently (For example, I stumbled across the дд/мм/гггг г. format which basically means dd/mm/yyyy y. Would that "y." at the end affect what is being stored as a variable in PHP? It just sits there, it's an abbreviation, it can't be changed by the user)
Not let the person enter a date higher than the current one. I'm thinking of adding a simple 13-years-old age limit. How can that be done?
Before asking this question, I have been searching for a solution to all these problems for a while now. And I found out about the checkdate() function but from what I learnt, it accepts only the mm/dd/yyyy format which is not something I want. And it also works a little bit differently. I need to input three separate values for day, month and year. So, I went to look for alternative solutions. I stumbled across this topic: Correctly determine if date string is a valid date in that format. The solution seems to be what I'm looking for. The only problem is that it only accepts the "yyyy/mm/dd" format. So, logically, I just have to find a way to detect what the format is (where my only concern is: what if the user opens Inspect Element and changes the input type... maybe the solution to this is a simple check if $_POST['birthday'] is a type="data" element first? I'm also still worried about that "г./y." which appears in some regions though). After the detection, the correct function for checking whether the date is valid or not will get iterated. After all of this, the date will be simply converted to yyyy/mm/dd and the website will make one last check to see if the user is at least 13-years-old and allowed to be registered. I don't get to work with PHP very often, so any kind of help is appreciated!
You should be able to use the PHP Date function by adding your input as string. Something like this:
$dob = date('Y-m-d', strtotime($_POST['birthday']));
This should take any date value input into the form an convert it to the format you want.
Then you could use date_diff to get the age in years and run a simple if statement:
$age = date_diff(date_create($dob), date_create('now'))->y;
if ($age <= 13)
{
...
}
Edit
It should also be able to convert any extras correctly:
$dob = date('Y-m-d', strtotime('02/01/2019 y'));
outputs: 2019-02-01
Edit 2
Based off of the accepted answer's edit here:
Looks like you can replace the '/' in a date with '-' and it should work:
$birthday = 15/05/1980;
$date = str_replace('/', '-', $birthday);
$dob = date('Y-m-d', strtotime($date));
This worked on my local server. Hopefully it helps! It also worked with the other date formats previously discussed.
Related
if have the following problem. in my html5 datefield, i have the input order dd.mm.yyyy (for example todays date: 27.04.2017).
<input type="date" />
thats correct in my country and timezone. the posted value is in reversed order to my input. its yyyy-mm-dd (for example todays date: 2017-04-27).
is there any way to change the timeformat if the the value is posted?
ive found several solutions but only for the input and not the posted values.
I'm not really sure what you mean but here is something you can try
$time = strtotime($_POST['dateInput']);
if ($time != false) {
$mydate = date('d-m-Y', $time));
}
is there any way to change the timeformat if the the value is posted?
The field submits using a standard format. This is consistent across browsers that support the date input type and is required by the standard.
The user interface, on the other hand, is not consistent across browsers.
You can reliably expect a date field to always submit in the form YYYY-MM-DD so you can write a parser for it in your server side code (and then format it however you like).
Solve this problem on the server.
(You /could/ use JavaScript to parse the date, format it, and write it to a hidden input every time the date input changes … but doing it server side is simpler).
Say I am assuming a date format of DDMMYYY is being sent to me. However, somebody may send 01022014, another may send 1022014, another may send 122014 and yet another the year can be given just as 14. This last case is not very significant. I am more worried about the day and the month.
How can I validate the date, and accept all of these format, and then reformat it to what I want in PHP?
Short answer is you can't. You have to enforce the formatting rule in the frontend somehow. For example, show the months as a select drop down to remove ambiguity and reduce the possibility of human errors.
Goal: Convert any local date to the according ISO date
My Approach: http://codepad.viper-7.com/XEmnst
strftime("%Y-%m-%d",strtotime($date))";
Upside: Converts a lot of formats really well
Downside / Problem: Converts strings and numbers that are obviously not a date. E.g.
strftime("%Y-%m-%d",strtotime("A")) => 2012-10-29
strftime("%Y-%m-%d",strtotime("1")) => 1970-01-01
Questions:
Is there a better way to identify and convert dates to ISO dates?
Do you know of any library / regex that is capable of do so in php?
PHP's strtotime() function already does a best-effort attempt at taking an arbitrary string and working out what date format it is.
I dislike this function for a number of reasons, but it does do a reasonable job of working things out, given a string of unknown date format as input.
However, even strtotime()'s best efforts can never be enough, because arbitrary date formats are ambiguous.
There is no way to tell whether 05-06-07 is meant to be the 5th of June 2007 or the 6th of May 2007. Or even the 7th June 2005 (yes, some people do write dates like that).
Simple plain truth: It's impossible.
If you want your dates to be reliable in any meaningfuly way, you must abandon the idea that you'll be able to accept arbitrary input formats.
[EDIT]
You say in the comments that the input is coming from a variety of Excel and CSV files.
The only hope you have is if each of those files is consistent in itself. If you know that a file from a given source will have a given input format, you can write a custom wrapper for each file type that you import, and process it for that format. This is a solution I've used myself in the past, and it does work as long as you can predict the format for the file you're processing.
However, if individual files contain unpredictable or ambiguous dates, then you are out of luck: You have an impossible task. The only way you'll avoid having bad data is to kick back to the suppliers of the files and ask them to fix their data.
I think the problems will really arise when faced with dates such as 5-6-2012 when it is unclear whether you are dealing with 5th June, or 6th May and you could be taking input from European countries where DD MM YYYY is the norm.
If you are analyzing just one input field, then you might have a chance of detecting the delimeters and splitting the string up looking for what might look like a real date.
In this case the PHP function checkdate might come in handy as a last ditch double check.
Be aware also that Mysql (if this is where the data is heading) is also quite lenient about what it will put into a DATE field, the delimeters, the absence of leading zeros etc. But still, you have to get the Y M D order correct for it to have a chance.
I suppose the ultimate answer is to disallow free-text input for dates, but give them pickers - but of course you may not be in a position to influence the incoming date ...
I have a script which is fed dates in numerous different formats.
I want to save these dates as timestamps so they can easily be manipulated/ordered.
When i try an convert a mm-dd-yyyy type date to a timestamp, it fails.
When the script runs, it does not know what format it will be fed, and as such this cannot be specified. Near all other formats of date seem to be converted fine.
Could anyone advise how to fix this, or alternatively an alternative way that all date formats can be converted to an orderable, consistent format that can be manipulated?
Many Thanks
It sees strings with - in them as dd-mm-yyyy and / as mm/dd/yyyy.
See also this question and the comments on the documentation.
Possible solutions / workarounds:
on php 5.3, use date_create_from_format
on older php and not on windows, use strptime
if neither can be used, either replace the - to / when necessary, or use one of the regexes suggested you can find through the linked question.
Note however that at some time you do need to know what the format is to start with. Computers are not mindreaders. They can't, and never will be able to, distinguish between mm-dd-yyyy and dd-mm-yyyy in the overlap ranges (both mm and dd <= 12) if you don't provide the distinction.
In my project I am importing users from a csv file. In that some columns have date values
Eg:- date of birth, project start date, project dead line date etc. I know the date column headers but the user can enter date format in different ways. How can I validate the value get from csv is a valid date or not?
While not always accurate, you can try strtotime(). It's not a perfect solution but it's worth trying. Just read the notes because it can have varying behavior depending on what your date formats look like.
The php function strtotime can take many different date formats and returns a timestamp. If your can make thoughtful assertions on the valid timestamp values, validation can be done with those assertions.
But it could be prone to side effects,like day and month mismatch, so it would be a poor validation. I suggest that you enforce a common date pattern on the input file.
I use Zend_Date, as the constructor will validate the date for me, but of course if you don't expect a precise format you'll get in the kind problems that #gordon points out with 11/10/09 type of date. This will generate you a valid date, but for a default locale/format which can be of course wrong.