in case of somone wonder 'last day of 1 month ago' is also posible (not only month names)
This page describes the different relative date/time formats that the strtotime(), DateTime and date_create() parser understands.
Description | Format |
---|---|
dayname |
'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' |
daytext |
'weekday' | 'weekdays' |
number |
[+-]?[0-9]+ |
ordinal |
'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' | 'seventh' | 'eighth' | 'ninth' | 'tenth' | 'eleventh' | 'twelfth' | 'next' | 'last' | 'previous' | 'this' |
reltext |
'next' | 'last' | 'previous' | 'this' |
space |
[ \t]+ |
unit |
(('sec' | 'second' | 'min' | 'minute' | 'hour' | 'day' |
'fortnight' | 'forthnight' | 'month' | 'year') 's'?) | 'weeks' |
daytext |
Format | Description | Examples |
---|---|---|
'yesterday' | Midnight of yesterday | "yesterday 14:00" |
'midnight' | The time is set to 00:00:00 | |
'today' | The time is set to 00:00:00 | |
'now' | Now - this is simply ignored | |
'noon' | The time is set to 12:00:00 | "yesterday noon" |
'tomorrow' | Midnight of tomorrow | |
'back of' hour |
15 minutes past the specified hour | "back of 7pm", "back of 15" |
'front of' hour |
15 minutes before the specified hour | "front of 5am", "front of 23" |
'first day of' | Sets the day of the first of the current month. This phrase is best used together with a month name following it. | "first day of January 2008" |
'last day of' | Sets the day to the last day of the current month. This phrase is best used together with a month name following it. | "last day of next month" |
ordinal space dayname space 'of' |
Calculates the x -th week day of the current month. |
"first sat of July 2008" |
'last' space dayname space 'of' |
Calculates the last week day of the current month. | "last sat of July 2008" |
number space ? (unit | 'week') |
Handles relative time items where the value is a number. | "+5 weeks", "12 day", "-7 weekdays" |
ordinal space unit |
Handles relative time items where the value is text. | "fifth day", "second month" |
'ago' | Negates all the values of previously found relative time items. | "2 days ago", "8 days ago 14:00", "2 months 5 days ago", "2 months ago 5 days", "2 days ago" |
dayname |
Moves to the next day of this name. | "Monday" |
reltext space 'week' |
Handles the special format "weekday + last/this/next week". | "Monday next week" |
Note:
Relative statements are always processed after non-relative statements. This makes "+1 week july 2008" and "july 2008 +1 week" equivalent.
Exceptions to this rule are: "yesterday", "midnight", "today", "noon" and "tomorrow". Note that "tomorrow 11:00" and "11:00 tomorrow" are different. Considering today's date of "July 23rd, 2008" the first one produces "2008-07-24 11:00" where as the second one produces "2008-07-24 00:00". The reason for this is that those five statements directly influence the current time.
Note:
Observe the following remarks when the current day-of-week is the same as the day-of-week used in the date/time string. The current day-of-week could have been (re-)calculated by non-relative parts of the date/time string however.
- "
dayname
" does not advance to another day. (Example: "Wed July 23rd, 2008" means "2008-07-23").- "
number
dayname
" does not advance to another day. (Example: "1 wednesday july 23rd, 2008" means "2008-07-23").- "
number
weekdayname
" will first add the number of weeks, but does not advance to another day. In this case "number
week" and "dayname
" are two distinct blocks. (Example: "+1 week wednesday july 23rd, 2008" means "2008-07-30").- "
ordinal
dayname
" does advance to another day. (Example "first wednesday july 23rd, 2008" means "2008-07-30").- "
number
weekordinal
dayname
" will first add the number of weeks, and then advances to another day. In this case "number
week" and "ordinal
dayname
" are two distinct blocks. (Example: "+1 week first wednesday july 23rd, 2008" means "2008-08-06").- "
ordinal
dayname
'of' " does not advance to another day. (Example: "first wednesday of july 23rd, 2008" means "2008-07-02" because the specific phrase with 'of' resets the day-of-month to '1' and the '23rd' is ignored here).Also observe that the "of" in "
ordinal
space
dayname
space
'of' " and "'last'space
dayname
space
'of' " does something special.
- It sets the day-of-month to 1.
- "
ordinal
dayname
'of' " does not advance to another day. (Example: "first tuesday of july 2008" means "2008-07-01").- "
ordinal
dayname
" does advance to another day. (Example: "first tuesday july 2008" means "2008-07-08", see also point 4 in the list above).- "'last'
dayname
'of' " takes the lastdayname
of the current month. (Example: "last wed of july 2008" means "2008-07-30")- "'last'
dayname
" takes the lastdayname
from the current day. (Example: "last wed july 2008" means "2008-06-25"; "july 2008" first sets the current date to "2008-07-01" and then "last wed" moves to the previous Wednesday which is "2008-06-25").
Note:
Relative month values are calculated based on the length of months that they pass through. An example would be "+2 month 2011-11-30", which would produce "2012-01-30". This is due to November being 30 days in length, and December being 31 days in length, producing a total of 61 days.
Note:
number
is an integer number; if a decimal number is given, the dot (or comma) is likely interpreted as delimiter. For instance,'+1.5 hours'
is parsed like'+1 5 hours'
, not as'+1 hour +30 minutes'
.
版本 | 说明 |
---|---|
7.0.8 | Weeks always start on monday. Formerly, sunday would also be considered to start a week. |
in case of somone wonder 'last day of 1 month ago' is also posible (not only month names)
@Igor, @Mark Simon, seems that was fixed.
PHP 7.4.10
<?php
new DateTimeImmutable('midnight first day of');
/* date: 2020-09-01 00:00:00.0 UTC (+00:00) */
new DateTimeImmutable('midnight first day of next month next year');
/* date: 2021-10-01 00:00:00.0 UTC (+00:00) */
?>
Both dayname AND daytext ("weekday"/"weekdays") reset time information to 0.
Depending on how accurate you need it, the following may work for you:
new DateTime('last weekday ' . date('H:i:s'));
new DateTime('last weekday ' . (new DateTime())->format('H:i:s.u'));
(As documented, date() doesn't handle microseconds.)
@Mark Simon, while you're correct, it's still possible to get first/last day of the year using relative date formats, though in a somewhat roundabout way.
<?php
echo gmdate('F j, Y', strtotime('first day of january this year'));;
/* Output: January 1, 2018 */
echo gmdate('F j, Y', strtotime('last day of december this year'));;
/* Output: December 31, 2018 */
?>
I'm not sure if this is a bug or expected. As erwin points out :
"first monday of may 2011" is invalid, but "first monday may 2011" does work. Simply omit "of" if above examples do not work.
This still applies in 5.5 as well, and I ran into it while building out a utility to check if a day was a holiday.
Meaning "fourth day July 2016" /works/, but "fourth day of July 2016" does not. It will return an error. I emphasize works, because "fourth day July 2016" actually returns 2016-07-05. So you'll need "third day July 2016" for the Fourth of July.
However, "Last Monday May 2016" and "Last Monday of May 2016" ( for Memorial Day ) are both /valid/, but produce different results. The first returns 2016-04-25, which is incorrect, while the second returns the correct 2016-05-30.
Get the first day of a month, in a typical calendar month, typically the Monday in the first week of the month. In my example when the code is ran at 2016-04-06, 1st of april will be a Friday, since Calendars typically start on monday, this is the date you might want, in this case this would be 28th of March.
<?php
/* Code ran at 2016-04-06 */
$date = new DateTime('first day of this month');
$date->modify('monday this week');
echo $date->format('Y-m-d');
/* Output: 2016-03-28 */
?>
Note that expressions such as "last day of" and "first day of" imply a day of a month, not, for example of the year or week.
So, expressions, such as "first day of this year" will give the first day of this month, with no apparent regard for the year.
As powerful as the parser is, it can lead to disappointing or confusing results.
oguzkonya34 at gmail dot com
Point of correction:
Apparently 'next week' advances the week if and only if the day is Sunday. This:
<?php
echo date('F jS, Y', strtotime('Monday next week 2012-03-31'));
?>
would still return April 2nd.
Quote "
Apparently 'next week' advances the week if and only if the day is Sunday. "
Not really. 2012-03-31 would be Saturday if 2012-04-01 is Sunday as you mentioned. Then Monday next week for 2012-03-31 is April 2nd which is correct.
Using strtotime('DAYNAME') like strtotime('Tuesday') returns midnight on the specified day. It doesn't preserve the current time or the time passed into the function.
April 1st, 2012 is Sunday. You might expect to get April 2nd, 2012 with 'Monday next week', however this:
<?php
echo date('F jS, Y', strtotime('Monday next week 2012-04-01'));
?>
returns April 9th, 2012. To get April 2nd, you need to use this:
<?php
echo date('F jS, Y', strtotime('next Monday 2012-04-01'));
?>
Apparently 'next week' advances the week if and only if the day is Sunday. This:
<?php
echo date('F jS, Y', strtotime('Monday next week 2012-03-31'));
?>
would still return April 2nd.
Just for those who want the last day of the year without calling the function twice:
<?php
echo date('Y-m-d',
strToTime('1/1 next year -1 day')
);
// 2011-12-31
?>
For reference this is actually saying "Take the first day of the first month next year, then subtract 1 day".
If the ordinal being used is "last" and the next month is n, use the "n 1". Otherwise, if the previous month is p and it has d number of days in it, use "p d".
For example: "last thursday of November" becomes "last thursday December 1" and "fourth thursday of November" becomes "fourth thursday September 30th"
Hopes this helps someone out there.
Month skipping has issues with number of days in the month.
'+1 month' may move to the following month if the next month has less days than the current:
<?php print date('d M Y H:i:s', strtotime('+1 month', strtotime('Thu Mar 31 19:50:41 IST 2011'))); ?>
Prints: 01 May 2011 19:50:41
But with 'last day of +1 month' the result is different:
<?php print date('d M Y H:i:s', strtotime('last day of +1 month', strtotime('Thu Mar 31 19:50:41 IST 2011'))); ?>
Prints: 30 Apr 2011 19:50:41
(PHP 5.3.3)