Formatos relativos

Esta página descreve os diferentes formatos de data e tempo relativos que os interpretadores strtotime(), DateTime e date_create() entendem.

Símbolos Utilizados
Descrição Formato
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
Notação baseada no dia
Formato Descrição Examplos
'yesterday' Meia-noite de ontem "yesterday 14:00"
'midnight' A hora é configurada para 00:00:00  
'today' A hora é configurada para 00:00:00  
'now' Agora - isto é simplesmente ignorado  
'noon' A hora é configurada para 12:00:00 "yesterday noon"
'tomorrow' Meia-noite de amanhã  
'back of' hour 15 minutos após a hora informada "back of 7pm", "back of 15"
'front of' hour 15 minutos antes da hora informada "front of 5am", "front of 23"
'first day of' Define o dia para o primeiro dia do mês atual. Essa frase é usada de melhor forma, junto com um nome de mês. "first day of January 2008"
'last day of' Define o dia para o último do mês corrente. Essa frase é usada de melhor forma, junto com um nome de mês. "last day of next month"
ordinal space dayname space 'of' Calcula o número ordinal x-th da semana do mês corrente. "first sat of July 2008"
'last' space dayname space 'of' Calcular o último dia da semana do mês corrente. "last sat of July 2008"
number space? (unit | 'week') Manipula porções de tempo relativas onde o valor seja um número. "+5 weeks", "12 day", "-7 weekdays"
ordinal space unit Manipula porções de tempo relativas onde o valor seja um texto. "fifth day", "second month"
'ago' Nega todos os valores das porções de tempo relativas anteriores. "2 days ago", "8 days ago 14:00", "2 months 5 days ago", "2 months ago 5 days", "2 days ago"
dayname Move para o próximo dia deste nome. "Monday"
reltext space 'week' Manipula o formato especial "weekday + last/this/next week". "Monday next week"

Nota:

Declarações relativas são sempre processadas depois de declarações não relativas. Isso faz com que "+1 week july 2008" e "july 2008 +1 week" sejam equivalentes.

As exceções desta regra são "yesterday", "midnight", "today", "noon" e "tomorrow". Observe que "tomorrow 11:00" e "11:00 tomorrow" são diferentes. Considerando que a data hoje como "July 23rd, 2008", o primeiro produzirá "2008-07-24 11:00" assim como o segundo produzirá "2008-07-24 00:00". Isso acontece por que as cinco declarações influenciam diretamente o tempo corrente.

Nota:

Observe as seguintes considerações quando o dia da semana corrente é o mesmo que o dia da semana utilizada na string date/hora. O dia da semana corrente pode ser (re-)calculado para porções não relativas de strings de data/hora.

  1. "dayname" não avança para outro dia. (Examplo: "Wed July 23rd, 2008" referencia "2008-07-23").
  2. "number dayname" não avança para outro dia. (Exemplo: "1 wednesday july 23rd, 2008" referencia "2008-07-23").
  3. "number week dayname" adicionará primeiro o dia da semana, mas not avançará para outro dia. Neste caso, "number week" e "dayname" são dois blocos distintos. (Exemplo: "+1 week wednesday july 23rd, 2008" referencia "2008-07-30").
  4. "ordinal dayname" avançarápara outro dia. (Exemplo "first wednesday july 23rd, 2008" referencia "2008-07-30").
  5. "number week ordinal dayname" adicionará primeiro o número de semanas, e então avançará para outro dia. Neste caso "number week" e "ordinal dayname são dois blocos distintos. (Exemplo: "+1 week first wednesday july 23rd, 2008" referencia "2008-08-06").
  6. "ordinal dayname 'of' " não avança para outro dia. (Exemplo: "first wednesday of july 23rd, 2008" referencia "2008-07-02" porque a frase específica com 'of' redefine o dia do mês para '1' e o '23rd' é ignorado).

Também observe que o "of" em "ordinal space dayname space 'of' " e "'last' space dayname space 'of' " fazem coisas especiais.

  1. Ele definirá o dia do mês para 1.
  2. "ordinal dayname 'of' " não avançará para outro dia. (Exemplo: "first tuesday of july 2008" referencia "2008-07-01").
  3. "ordinal dayname " avançará para outro dia. (Exemplo: "first tuesday july 2008" referencia "2008-07-08", veja também o item 4 na lista acima).
  4. "'last' dayname 'of' " captura o último dayname do mês corrente. (Exemplo: "last wed of july 2008" referencia "2008-07-30")
  5. "'last' dayname" captura o último dayname do mês corrente. (Exemplo: "last wed july 2008" referencia "2008-06-25"; "july 2008" primeiro definirá a data corrente para "2008-07-01" e então "last wed" moverá para a última Quarta-feira que será "2008-06-25").

Nota:

Meses com valores relativos são calculados baseados no tamanho do mês passado. Um exemplo seria "+2 month 2011-11-30",que produziria "2012-01-30". Isso é devido a Novembro tendo 30 dias como tamanho, e Dezembro tendo 31, produzindo um total de 61 dias.

Changelog

Versão Descrição
5.3.3 "first day" e "last day" foi modificado para ter o comportamento de "+1 day" e "-1 day", respectivamente. Anteriormente, o comportamento era como "first day of" e "last day of".

add a note add a note

User Contributed Notes 13 notes

up
38
Mark Simon
8 years ago
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.
up
18
oguzkonya34 at gmail dot com
12 years ago
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.
up
11
Igor
6 years ago
@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 */
?>
up
5
phpnet at rudde dot org
8 years ago
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 */
?>
up
11
geneticdrift
13 years ago
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)
up
3
chris at burnhamup dot com
11 years ago
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.
up
2
InvisibleSmiley
3 years ago
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.)
up
1
yaroslav429 at gmail dot com
3 years ago
@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) */
?>
up
0
php at rcs dot us
7 years ago
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.
up
-2
matt
12 years ago
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.
up
-16
Pseudoname
9 years ago
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.
up
-18
scragar at gmail dot com
12 years ago
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".
up
-4
mike
3 years ago
in case of somone wonder 'last day of 1 month ago' is also posible (not only month names)
To Top