I really like the PHP function strtotime(), but the user manual doesn't give a complete description of the supported date formats. It only gives a few examples like "10 September 2000", "+1 week 2 days 4 hours 2 seconds", and "next Thursday".
Where can I find a complete description?
I can't find anything official, but I saw a tutorial that says strtotime()
uses GNU Date Input Formats. Those are described in detail in the GNU manual.
One discrepancy I notice is that "next" doesn't match the
behaviour described in the GNU manual. Using strtotime(), "next Thursday" will give you the same result as "Thursday", unless today is a Thursday.
If today is a Thursday, then
strtotime("Thursday") == strtotime("today")
strtotime("next Thursday") == strtotime("today + 7 days")
If today is not a Thursday, then
strtotime("Thursday") == strtotime("next Thursday")
I'm using PHP 5.2.6.
Update:
I guess the user manual has been updated since I posted this, or else I was blind. It now contains a link to the Date and Time Formats chapter, that includes a section on relative formats.
You can start to trace what it is doing by looking at the following C code:
http://cvs.php.net/viewvc.cgi/php-src/ext/date/php_date.c
Search for PHP_FUNCTION(strtotime)
Also this is the main regex parsing:
http://cvs.php.net/viewvc.cgi/php-src/ext/date/lib/parse_date.re
Good luck
In my experience strtotime() can accept anything that even remotely looks like a date. The best way to figure out its boundaries are is to create a test script and plug in values and see what does and doesn't work.
$input = "Apr 10th";
print(date('Y-m-d', strtotime($input)));
Just keep changing the $input variable and observe the results.
Basically anything that date can create strtotime will parse. With one exception, it does have issues with non-US style formatting. So keep it Month-Day-Year type formatting in place.
Related
strtotime() in PHP is quite powerfull function. One of it's features is relative dates.
For example this command:
echo date('Y-m-d', strtotime('Sunday this week'));
produces 2016-02-14 on my machine (today is "2016-02-12", Friday). Thus it supposes that first day of week is Monday. However in different locales countries first day of week is different.
Is there a way to change this behaviour and make strtotime() think that first week day is Sunday?
As discussed in the comments of the question, it may be better to rely on a custom function, which is tested and will most probably produce the same result on every machine.
A function like this could be:
<?php
function x() {
return date('Y-m-d', date('N')==7 ? strtotime('today') : strtotime('last sunday'));
}
echo x();
You find a demo here.
If you have many machines to deploy your code to, you could additionally include a test script in the installation process which tests if it gets correct results from this (and other things that may vary depending on installation).
PHP 5.5 introduced the Internationalization extension, which among many useful functions provides and IntCalendar class. It has a static function getFirstDayOfWeek which can be used to get the first day of the week, based a locale.
Straight from the docs:
ini_set('date.timezone', 'UTC');
$cal1 = IntlCalendar::createInstance(NULL, 'es_ES');
var_dump($cal1->getFirstDayOfWeek()); // Monday
When I try to get week number from the date, I am getting different numbers with ISO and US standard.
$date = mktime(0, 0, 0, 01, 01, 2006);
$week = (int)date('W', $date);
echo "Weeknummer: ".$week;
Because ISO standard says that week start on Monday...US standard says that week start on Sunday
How can I sort this out using PHP code or some external API available for this? Any paid one something ?
This link will tell you how to check this online
http://www.onlineunitconversion.com/day_week_number.html
Please Help... I want to get the US standard week number
There is no obvious way to do what you want utilising the PHP date functions themselves (that I know of), the next best alternative would be to use a function to calculate your week number seperately.
function week_number($stamp){
return date('W', $stamp+(60*60*24));
}
http://codepad.org/IvX9jqEj
Use date_default_timezone_set and define default timezone. Then you should have right number.. From php.net
I am trying to put a readable time and date as part of a file name (in php). I am having all kinds of trouble with this and was hoping someone could help. I have tried several different recommendations that I have read around the internet (plus I read the manual) but I really haven't gotten anything to work right. Right now I have this:
$Time=strtotime("now");
$date=DateTime::createFromFormat('m/d/Y H:i:s', '7/24/2012 14:40:30');
$date_readable=$date->$Timestamp();
At that point I then add $date_readable to a file name. It compiles and runs but it doesn't format the date at all. It still gives it as a timestamp.
Any suggestions on how to make this work?
you can do it with simple date function for example
$time = strtotime("now");
$formatDate = date('F jS, Y h:i:s A', $time);
echo $formatDate;
this will print something like
July 25th, 2012 1:02:29 am
DateTime class is more powerful then using simple date function, as DateTime class offers powerful API's plus it is object oriented. however for simple date conversions i would stick to php's date function. as that could do my purpose.
for more formatting option have a look at this link http://www.php.net/manual/en/function.date.php#refsect1-function.date-parameters
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
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.