strtotime with year in 2 digit format - php

Hallo can someone explain the behaviour of strtotime function with year in non-standard format.
echo date("d-m-Y",strtotime('02-12-10')) .'<br>'; //10-12-2002
echo date("d-m-Y",strtotime('09.09.10')) .'<br>'; //02-09-2010 --How this is interpreted?
echo date("d-m-Y",strtotime('02-12-2010')) .'<br>'; //02-02-2010
echo date("d-m-Y",strtotime('09.09.2010')) .'<br>'; //09-09-2010
I wanted to convert strings of format dd.mm.yy(09.09.10) to datetime format.

strtotime() can be a bit flaky in such cases. It is built to recognize standard american date formats.
If you can use PHP > 5.3, consider using DateCreateFromFormat which has the big advantage of accepting a pre-defined format string to parse the incoming data.
On pre-5.3 platforms, strptime() seems to offer a second-best alternative. It's not available on Windows and has some minor issues - be sure to read the manual page before using.

From the manual:
The "Day, month and two digit year, with dots or tabs" format (dd [.\t] mm "." yy) only works for the year values 61 (inclusive) to 99 (inclusive) - outside those years the time format "HH [.:] MM [.:] SS" has precedence.
You are using '09.09.10' and 10 does not fall in the valid range hence change the separator to -

This is not 2-digit year question.
this is non-standard format question.
And asking impossible things from mere a program.
Even me, not being a computer, have no idea what these 09's dooes mean in your date. is it day.month.year? or year.month.day or whatever?
Assuming it's day.month.year:
$list($d,$m,$y) = explode("09.09.10");
echo "$d-$m-20$y";

Related

How to convert "Day, dd Month yyyy" to "yyyy-mm-dd" in php [duplicate]

This question already has answers here:
Convert one date format into another in PHP
(17 answers)
Closed 8 years ago.
How can I convert this:
Thursday, 14 August 2014
to this in php:
2014-08-14
I tried strtotime(), trim(), etc.. and realised thats not it. Can you guide me on this one please?
It works just fine for me with strtotime.
$time = strtotime("Thursday, 14 August 2014");
echo date("Y-m-d",$time);
if you're facing the problem of converting a human readable date to numeric values you have to reconsider your design. Your code should work only with 32 or 64 bit epoch values (seconds since 1st January 1970) and then convert them into the appropriate format only when needed.
In any case, just do this:
$time = strtotime(stripslashes("Thursday, 14 August 2014"));
echo date("Y-m-d",$time);
remember to strip out slashes and commas because they can confuse strtotime
I would avoid such a solution because it's NOT portable. You'll find PHP versions in which such solution doesn't work, moreover slightly different input strings could make strtotime to fail and most of all -> locale matters!!!! (i.e. what if the string is in italian language???)
Just work with epoch values and make a conversion only to show them to the end user! :-)
First convert Convert the string to time using strtotime() and than use date() function in php to do this. this function formats a local date and time, and returns the formatted date string.
Your code should look like this
<?php
$orignaltime = strtotime("Thursday, 14 August 2014");
echo date("Y-m-d",$orignaltime);

strtotime of today

Hallo, I want to find the difference between today and another date,
convert todays date into unix time format here
<?php
echo '1st one'.strtotime(date("d.m.Y")).'<br>';
echo '2nd one'.strtotime(date("m.d.Y")).'<br>';
?>
The first echo is producing some value, but not the second one. What is the bug in it...please help..
strtotime makes assumptions based on the date format you give it. For instance
date("Y-m-d", strtotime(date("d.m.Y"))) //=> "2010-09-27"
date("Y-m-d", strtotime(date("m.d.Y"))) //=> "1969-12-31"
Note that when given an invalid date, strtotime defaults to the timestamp for 1969-12-31 19:00:00, so when you end up with an unexpected date in 1969, you know you're working with an invalid date.
Because strtotime is looking for day.month.year when you use . as the delimiter, so it sees "9.27.2010" as the 9th day of the 27th month, which obviously doesn't exist.
However, if you change it to use / as the delimiter:
date("Y-m-d", strtotime(date("d/m/Y"))) //=> "1969-12-31"
date("Y-m-d", strtotime(date("m/d/Y"))) //=> "2010-09-27"
In this case, strtotime expects dates in month/day/year format.
If you want to be safe, Y-m-d is generally a good format to use.
It's worth pointing out that strtotime() does accept words like "today" as valid input, so you don't need to put a call to date() in there if all you want is today's date. You could just use strtotime('today');.
Come to think of it, a simple call to time(); will get you the current time stamp too.
But to actually answer the question, you need to consider that d.m.Y and m.d.Y are ambiguous - if the day of the month is less than the 12th, it is impossible to tell which of those two date formats was intended. Therefore PHP only accepts one of them (I believe it uses m/d/Y if you have slashes, but for dots or dashes it assumes d-m-Y.
If you're using strtotime() internally for converting date formats, etc, there is almost certainly a better way to do it. But if you really need to do this, then use 'Y-m-d' format, because it's much more universally reliable.
On the other hand, if you're accepting date input from your users and assuming that strtotime() will deal with anything thrown at it, then sadly you're wrong; strtotime() has some quite big limitations, of which you've found one. But there are a number of others. If you plan to use strtotime() for this sort of thing then you need to do additional processing as well. There may also be better options such as using a front-end Javascript date control to make it easier for your users without having to rely on strtotime() to work out what they meant.
strtotime does not consider 09.27.2010 to be a valid date...
You could check it like this:
<?php
// will return false (as defined by the docs)
echo var_dump(strtotime("09.27.2010"));
?>
The function expects to be given a string containing a US English date format and will try to parse that format into a Unix timestamp. US time format is : MM DD YYYY
look here for the Information about which formats are valid http://www.php.net/manual/en/datetime.formats.php. But what do you mean with deference between 2 dates? You mean the Timespan between 2 dates?
echo (time() - strotime("- 2 days")) . " seconds difference";
Something like that?
strtotime would not take the d.m.y format. good way is Y-m-d

Shortest way to compare 2 dates in dd/mm/yyyy format

can anyone suggest the neatest way to do this comparison? I need to test if a date provided in dd/mm/yyyy format is less than a fixed date, e.g 01/05/2009 - I know I can convert these to unix time format using strtotime, then make the comparison, but I'm curious if there is a quicker way to do it - many thanks, just looking for a hint to improve my code!
One option is just to reverse the format - create a string of the form
yyyy/mm/dd
That's a sortable format, so you can just do an ordinal string comparison. Of course, this means you won't detect invalid data etc.
There's probably not a shorter way code wise, and I wouldn't bother optimizing this unless you're sure it's a bottleneck.
However, as long as you're sure it will always be the exact same format (including 2 digits for month and day and with 0s) you should be able to reorder the string to put the year first, then the month, and then the day, and then just compare the strings.
However, I'm not sure this would be faster than just letting the libraries convert to unix time and then comparing those.
If you can change the format that the dates are stored in, you could define them as yyyy/mm/dd and then just compare the strings.
I think that your solution of converting it to Epoch then doing a comparison is as fast and as clean as your going to get.
if you want to improve your code, I would suggest you to use DateTime class. It's been introduced in php 5.2.0 (so, it still might not be supported on all servers)
in php 5.3.0 you can write something like this:
$d1 = DateTime::createFromFormat('d/m/Y', '02/03/2009');
$d2 = DateTime::createFromFormat('d/m/Y', '02/05/2009');
$interval = $d1->diff($d2);
echo $interval->format('%R%d days');
Well, you could use the PHP date class, but I am not sure it would be any better than you current solution...
http://php.net/manual/en/book.datetime.php
use this method
yearmonthday
you have 01.05.2010 and 03.07.2010
and to compare : 20100501 <= or => 20100703
$fixedDate = '01/05/2009';
$variableDate = '28/04/2010';
// Now we do our timestamping magic!
$fixedDate = implode('', array_reverse(explode('/', $fixedDate)));
$variableDate = implode('', array_reverse(explode('/', $variableDate)));
if ($variableDate < $fixedDate) // 20100428 < 20090501
{
// there you go
}

Correct Regular expressions to match a date

What is the correct regular expression to use to validate a date like. 2009-10-22 or 2009-01-01 etc. Platform PHP
This (from regexplib.com) will match what you want, and perform checks for leap years, days-per-month etc. It's a little more tolerant of separators than you want, but that can be easily fixed. As you can see, it's rather hideous.
Alternatively (and preferably in my opinion) you may want to simply check for figures in the correct places, and then perform leap year and days-per-month checks in code. Sometimes one regexp isn't so understandable and there's greater clarity in performing the checks in code explicitly (since you can report precisely what's wrong - "only 30 days in November", rather than a "doesn't match pattern" message, which is next to useless)
If you want something simple that does a little more than just validates format, but doesn't go as far as validating how many days is in the month that is entered, or leap years, you can use this:
^(19|20)[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
This example allows years 19xx and 20xx
As you have to deal with accepting 2009-02-28 but not 2009-02-29 but accept 2008-02-28 you need more logic that 1 think a regex can give. (But if someone can show it I would be impressed)
I would try to convert it to a date and report if the conversion failed or if you you language has a check date function use that.
\d{4}-\d{2}-\d{2} would match string in that form, but to check if date is valid, you'd had to break that string to year, month and date (you can use this regexp for that) parts and check each of them.
You can additionally, make sure that year must start with 1 or 2: [12]\d{3}-\d{2}-\d{2}, and you can also do the same for month and day: [12]\d{3}-[01]\d-[0123]\d (but I would go with the first regexp and compare parts "manually")
found this on the web tested it with a few dates and looks stable, for dates between 1900 and 2000:
(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])
OK, a regex that will validate month and day ranges could be
[0-9]{4}-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])
If you want to restrict the years, say, from 1900 to 2050, you could end up with
(?:2050|20[0-4][0-9]|19[0-9]{2})-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])
They will not catch "subtly wrong" dates like February 31st, so it's really quite clear that a sanity check needs to be performed outside of the regex.
In .NET Regex:
\d{4}\-\d{2}\-\d{2}
[0-9]{4}-[0-9]{2}-[0-9]{2}
or
\d\d\d\d-\d\d-\d\d
or
...
simply read first regex tutorial
^\d{4}-\d{2}-\d{2}$
but no regular expression can prevent someone to enter "9867-39-56"
For a complete validation (which would include verifying that the day, month and year parts are valid) a Regex is not the tool of choice. Apart from month issues you'd get into trouble with leap years...
So, if you just want to check if the rough format is correct, or isolate the different parts (year-month-day), a regex is fine.
([0-9]{1,4})-(1[012]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])
This is already pretty exact and captures the year (0..9999), month and day into capture groups, ready for parsing...
If you can rely on more than a regular expression, an hybrid solution by using Posix functions date() and time() delivered with PHP could look like this:
<?php
date_default_timezone_set("GMT");
function validateDate($date)
{
if (preg_match("^[0-9]{4}-[0-9]{2}-[0-9]{2}^", $date))
{
return date('Y-m-d', strtotime($date)) === $date;
}
return false;
}
// Some tests
$dates = array(
'2009-09-09', '2009-09-32', '2009-31-00', '2035-01-02',
);
foreach($dates AS $date)
{
echo $date .': '. (validateDate($date) ? 'OK' : 'FAILS') ."\n";
}
?>
It's not elegant plus you'll be limited by Unix Epoch time (from January 1 1970 00:00:00 GMT to January 19 2038 03:14:07 GMT), but it's reliable and it's well supported in PHP.

PHP : Better date parser than strtotime

I'm trying to parse a string in a specific format and I'm really surprised to discover that I can't find a good function to do that.
The only one I found is strtotime and it doesn't fit as it guesses the date format. I really don't trust the "guess" part.
Moreover my string input is in a french format (dd/mm/aaaa) which it seems that it's not well understood (it parses american formats like mm/dd/aaaa).
What I'm looking for is a function that take in input a date string and a format to parse.
I could do it myself with a regexp but I can't believe that it doesn't already exist.
I found :
DateTime::createFromFormat(). But it only work with PHP 5.3 and I don't have the power to upgrade the PHP version (5.2)
strptime(). This method does what I want but is not implemented on windows platform (by the way: WTF ??)
Any suggestion ?
Unfortunately, it seems that such parsing is better done manually, by exploding the string at slashes and then switching day and month.
Check out Zend_Date, which lets you specify the format when you set a date. As well as including constants for many common formats, you can specify your own too.
$date = new Zend_Date();
$date->set('27/08/2009','DD/MM/YYYY');
The following comment from php.net on strtotime may help:
Fails for non-US dates where the
ordering is uncertain, such as
01/02/2003 - parses this as Feb 1st,
rather than Jan 2nd.
If you are parsing dates for a non-US
locale, you can flip these elements of
your date:
<?php
$y = $_POST['date'];
if (preg_match('/^\s*(\d\d?)[^\w](\d\d?)[^\w](\d{1,4}\s*$)/', $y, $match)) {
$y = $match[2] . '/' . $match[1] . '/' . $match[3];
}
echo date('d # m # Y', strtotime($y));
?>
WARNING: Above only works for dates,
and breaks for times: 12:30:01 will be
converted to 30/12/01.
I've written a class myself, I think you'll find an ok version in gadmdatecommand.php in http://sourceforge.net/projects/phpdbedittk
Regarding the comments here to just explode by '/' and swap the number, its not quite that simple. If you offer to enter dates into an input box, you may get - depending on the locality of the user and the application
1/7/2010
1.7.2010
1-7-2010
15 Jul
1 Jul 2010
1/6/8
and many more variations. I've solved this problem (at least for me successfully) by creating dateformats, each of which have
a) a regex that matches the format
b) an array mapper that matches regex brackets into date pieces (day, month, minute, am/pm)
c) an output format for date()
HTH
If you know your date format input will be English-formatted, then you can process it into a more standard date format. A simple parsing of 24/7/2007 to 2007-07-24 is trivial. Explode with the forward slash and put the parts in the right spot. I know for a fact that strtotime will parse 2007-07-24 correctly.
strptime():
Internally, this function calls the strptime() function provided by the system's C library. This function can exhibit (!) noticeably different behaviour across different operating systems. The use of date_parse_from_format(), which does not suffer from these issues, is recommended on PHP 5.3.0 and later.
http://www.php.net/manual/en/function.strptime.php

Categories