Currently working with a company that sends info via XML which is read and inserted into our database and they've asked how they want us to send dates through, string, integer timestamp etc and it peaked my curiosity a little for me to google but not able to find the answer to the following question.
If a string for a date is sent as 03/01/2016 how does php when convert into a timestamp using strtotime() determine the format?
UK its read as 3rd January 2016 but to the US its 1st March 2016 so how does php know to convert it to the correct region?
Does it use timezone set in the php.ini? does something have to be declared beforehand.
Never really though about it and curious to know as it would probably make my dealings a lot easier in future if information such as a date is given to me in that format
strtotime() returns timestamp and it only parses date in specific format like "m/d/y" or "d-m-y" or "d.m.y". It is clearly state on documentation that:
Each parameter of this function uses the default time zone unless a
time zone is specified in that parameter.
And regarding format accepted:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at
the separator between the various components: if the separator is a
slash (/), then the American m/d/y is assumed; whereas if the
separator is a dash (-) or a dot (.), then the European d-m-y format
is assumed.
To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD)
dates or DateTime::createFromFormat() when possible.
Hope it helps...
Related
I'm working on an application in Laravel 4 that needs users to input UK format dates (dd/mm/yyyy). At present the Laravel's Validator class is validating the format with no problem. However, some of the dates supplied also need to be in the future or need to be compared to each other. At present after: seems to be evaluating against US date format which isn't much help.
Is there any way that I can get Validator to recognise my date format or is it a case of me having to validate the input format first, convert the date and then validate it again to check that it's in the future?
Thanks.
The laravel doc says:
The field under validation must be a valid date according to the
strtotime PHP function.
The strtotime php doc states that this function parse in US format.
But a additionnal note states:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.
To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or DateTime::createFromFormat() when possible.
So I'll reccommend you tu force the use of - instead of / (with a validation or with a str_replace filter) or create a custom validator that uses DateTime::createFromFormat() as suggested in the php doc.
Maybe I'll do a push request to replace strtotime to DateTime::createFromFormat() in the default Validator if it is really more reliable (need to investigate the two first)
Good evŠµning!
echo date('r', strtotime('10.01.11'));
Prints: Sun, 05 Feb 2012 10:01:11
Expected: Mon, 10 Jan 2011 00:00:00
How do I force strtotime() to parse the input string as a date only? I have to convert a bunch of dates in different format. DateTime::format is not an option since I don't know all the formats the script will run into, and it's not even installed on the server (and i don't have privileges to do it).
Tried
strtotime('day 10.01.11'),
strtotime('10.01.11 00:00:00'),
strtotime('10.01.11 midnight')
- nothing worked.
Any help is much appreciated
How do I force strtotime() to parse the input string as a date only?
You don't. strtotime uses very well-defined parsing formats. What it generates will depend entirely on what you give it.
'10.01.11' is parsed as a time format, as it will always interpret three pairs of digits separated by periods as a time. It will recognize dates when separated by dashes, slashes or spaces. Annoyingly, there's an example there on the date format page that uses dots, but there doesn't seem to be a sure-fire way to force date parsing instead of time parsing. Sigh, PHP.
If you need that specific format to be interpreted as a date instead of a time, you have two options.
First, you can use a different date parsing method. If the expected format never changed, you could use DateTime::createFromFormat() or the horrifying strptime. You've indicated in comments that the format will vary and your PHP version is old enough not to have DateTime, so this might not work for you.
Second, you can pre-process the data. At least in this example, a conversion of . to / may do the trick, though 10/01/11 can be ambiguous as a date to humans. There's nothing wrong with a little regex sniffing to determine how to best process data.
There's also a third option: if you're getting this information from users, make your application begin forcing users to enter dates in a normal, consistent, parseable format. It may take some time to train your users to use YYYY-MM-DD, but it's probably the most sane long-term bet.
Is modifying the input an option for you?
$str = '10.01.11';
$str = str_replace('.', '/', $str);
echo date('r', strtotime($str));
However, this will still output Sat, 01 Oct 2011 00:00:00, according to the MM.DD.YY pattern (US standard).
EDIT: Depending on you usage, you might consider creating a list of regex patterns and parse the date accordingly. It is very hard to make a code like this to be open to all possibilities.
Tested, this works:
$date = DateTime::createFromFormat('d.m.y', '10.01.11');
echo $date->format('r');
http://codepad.viper-7.com/OH7Kyn
why don't you add the time set to 00:00:00 by default?
e.g.
echo date('D, d M Y H:i:s', strtotime('10.01.11'));
also strtotime uses the american date format so this will be translated into 1st of october 2011. it's easier to use the iso date format
I don't think strtotime knows how to parse those dates. To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates.
I've got a website where users can potentially type in their own dates before they're sent to the server. So I obviously need to parse what they give me and get it into a standard format before actually using it. So I used PHP's strtotime() function, which is pretty forgiving about what it will accept as input.
But I'm also using date.js on the site and its parse() function is pretty good, too. Should I use that on the user input before sending it to the server? Which one is better?
I'll keep strtotime() on the back end for safety, but if date.js is better I'll add that to the client.
(To clarify, I'm expecting mostly American date formats. But should that change, anything that eases that transition is preferred.)
As long as you feel strtotime() is meeting your needs, there isn't a great reason to change it on the client side. However, strtotime() makes a couple of assumptions which you need to stay on top of:
From the strtotime() documentation:
Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.
If you are allowing your client to send the date in any format they choose, the above could be a source of confusion. I just tested the dates 5/1/12 and 5-1-12 in date.js, and both were parsed as May 1st, 2012. PHP would interpret the two as May 1st 2012 and Jan 12th 2005(!!) respectively.
echo date("Y-M-n", strtotime("5/1/12"));
// 2012-May-5
echo date("Y-M-n", strtotime("5-1-12"));
// 2005-Jan-1 (whoops!)
However, pre-formatting the date has the obvious benefit of some insurance that the entered date is valid. Keeping strtotime() on the backend also ensures that you don't need a JavaScript-enabled client to send requests. Your PHP could still be called as a web service, etc, without the client needing to be a web browser.
Both.
You absolutely do need to validate the date in PHP, because one or more of your users may have disabled Javascript.
Javascript validation is nice because you can have a date entered in an input control, validate it in the onblur handler, and write the validated date back to the control. So after the user types the date of birth 2/5/01 and leaves the control, the date changes to 2 May 2001 and not only does the user knows that the date is interpreted correctly, but strtotime() also gets an unambiguous value.
You can also use much better validation feedback, from a UX point of view. Javascript can do the following (which is probably well known but it took a bit of searching for me to find it). Put an element in the page, like
<div id="DobReply"></div>;
Then the function which validates the Date of Birth can do
document.getElementById("DobReply").innerHTML = "Current age is "+age;
where age is a variable calculated from the entered date of birth, and today's date. As soon as the user leaves the control, the calculated age pops up, and if the user entered the current year (it happens) then she might spot the error immediately.
So I wouldn't get rid of datejs validation either. But all of this is lost if Javascript is disabled, you can get invalid dates, dates in weird formats, or anything. So if you can only have one, keep the strtotime().
I have different DateTime formats and need to convert them to a standardized format.
Is there any build in PHP method which accepts different formats and returning them as a DateTime object or something else easy to format? I searched php.net and also this forum but can't find anything.
Just want to save time before I start coding something which probably already exists.
my formats to catch:
d.m.Y
d/m/Y
d-m-Y
m.d.Y
m/d/Y
m-d-Y
Y.d.m
Y/d/m
Y-d-m
Y.m.d
Y/m/d
Y-m-d
If there is no PHP method I will write my own class or if someone has something handy to share... :)
Thanks!
You can use DateTime::createFromFormat and your formats in a loop and check if valid object has been created
I've been using PHP's strtotime() method to accept a date field on a form. I love how powerful it is, in how it will accept "Tomorrow", "Next Thursday", or (supposedly) any date representation and convert it to the Unix timestamp.
It's been working great -- until yesterday. Someone entered "2-4-10" and instead of logging Feb 4th, 2010, it logged April 10, 2002! So it expected Y-M-D instead of M-D-Y.
I thought maybe the problem was just using a 2-digit year, so we tried again with "2-4-2010". That logged April 2nd, 2010! At that point I just don't understand what strtotime() is doing. PHP.net says it expects a US English date format. Why then would it assume D-M-Y?
Is there a way around this? Or do I have to stop using strtotime()?
Note: I just now did a test. When you use slashes instead of hyphen/dashes, it works fine, even with 2/4/10. Why on earth does that matter? And if that's all it is, should I just run str_replace("-", "/", $input) on the form input before passing it to strtotime()?
The - indicates an ISO Date:
03-02-01 => 1. february 2003 (ISO)
01.02.03 => 1. february 2003 (European)
02/01/03 => 1. february 2003 (US)
The behavior of strtotime() is based largely on the GNU date input formats spec. But as powerful as it is, it shouldn't be expected to read minds. Allowing free-form user date input is asking for perpetual trouble.
I had this problem and solved it by doing exactly what you suggested - do a str_replace on the user-entered date to replace the dashes with slashes. This prevents strtotime from using an ISO date and solves the problem.
strtotime is by its very nature fuzzy, so you can't assume that it will always do what you want. If you enter 2010-04-02 then you would expect that to return 2nd April 2010, which is what strottime is trying to do. Running an str_replace from hyphens to slashes might mean that people entering in that format get the wrong date.
If you're running PHP 5.3 or above, consider date_parse_from_format() or for PHP 5.1 and above on Unix consider strptime(). Both functions take a format, so remove potential ambiguity (if you tell users what format you are expecting - if you're running an international site and have a text box labelled date which the user enters 2/4/2010 into then there is no way to know what their intended date is).