Formatos relativos

Esta página describe los diferentes formatos relativos de fecha/hora que entiende el analizador de strtotime(), DateTime y date_create().

Símbolos empleados
Descripción Formato
nombre del día 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
texto de día 'weekday' | 'weekdays'
número [+-]?[0-9]+
ordinal 'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' | 'seventh' | 'eighth' | 'ninth' | 'tenth' | 'eleventh' | 'twelfth' | 'next' | 'last' | 'previous' | 'this'
texto relativo 'next' | 'last' | 'previous' | 'this'
espacio [ \t]+
unidad (('sec' | 'second' | 'min' | 'minute' | 'hour' | 'day' | 'fortnight' | 'forthnight' | 'month' | 'year') 's'?) | 'weeks' | texto de día
Notaciones basadas en el día
Formato Descripción Ejemplos
'yesterday' Medianoche de ayer "yesterday 14:00"
'midnight' La hora es establecida a 00:00:00  
'today' La hora es establecida a 00:00:00  
'now' Ahora - esto es simplemente ignorado  
'noon' La hora es establecida a 12:00:00 "yesterday noon"
'tomorrow' Medianoche de mañana  
'back of' hora 15 minutos después de la hora especificada "back of 7pm", "back of 15"
'front of' hora 15 minutos antes de la hora especificada "front of 5am", "front of 23"
'first day of' Esteblece el día al primer día del mes en curso. Esta frase se utiliza mejor seguida de un nombre de mes. "first day of January 2008"
'last day of' Esteblece el día al último día del mes en curso. Esta frase se utiliza mejor seguida de un nombre de mes. "last day of next month"
ordinal espacio nombre del día espacio 'of' Calcula el x-ésimo día de la semana del mes en curso. "first sat of July 2008"
'last' espacio nombre del día espacio 'of' Calcula el último día de la semana del mes en curso. "last sat of July 2008"
número espacio? (unidad | 'week') Trata elementos de hora relativos donde el valor es un número. "+5 weeks", "12 day", "-7 weekdays"
ordinal espacio unidad Trata elementos de hora relativos donde el valor es texto. "fifth day", "second month"
'ago' Anula todos los valores de los elementos de hora relativos encontrados anteriormente. "2 days ago", "8 days ago 14:00", "2 months 5 days ago", "2 months ago 5 days", "2 days ago"
nombre del día Avanza al siguiente día con este nombre. "Monday"
texto relativo espacio 'week' Trata el formato especial "weekday + last/this/next week". "Monday next week"

Nota:

Las declaraciones relativas son siempre procesadas después de las declaraciones no relativas. Esto es, "+1 week july 2008" y "july 2008 +1 week" son equivalentes.

Las excepciones a esta regla son: "yesterday", "midnight", "today", "noon" y "tomorrow". Téngase en cuenta que "tomorrow 11:00" y "11:00 tomorrow" son diferentes. Considerando la fecha de hoy como "July 23rd, 2008", el primero produce "2008-07-24 11:00", mientras que el segundo produce "2008-07-24 00:00". La razón de esto es que esas cinco declaraciones influyen directamente en el instante actual.

Nota:

Analice las siguiente observaciones cuando el día de la semana actual es el mismo que el día de la semana usado en la cadena de fecha/hora. Sin embargo, el día de la semana actual prodría haber sido (re)calculado mediante partes no relativas de la cadena de fecha/hora.

  1. "nombre del día" no avanza a otro día. (Ejemplo: "Wed July 23rd, 2008" significa "2008-07-23").
  2. "número nombre del día" no avanza a otro día. (Ejemplo: "1 wednesday july 23rd, 2008" significa "2008-07-23").
  3. "número week nombre del día" añadirá primero el número de semanas, pero no avanzará a otro día. En este caso "número week" y "nombre del día" son dos bloques distintos. (Ejemplo: "+1 week wednesday july 23rd, 2008" significa "2008-07-30").
  4. "ordinal nombre del día" avanza a otro día. (Ejemplo "first wednesday july 23rd, 2008" significa "2008-07-30").
  5. "número week ordinal nombre del día" primero añadíra el número de semanas, y después avanzará a otro día. En este caso "número week" y "ordinal nombre del día" son dos bloques distintos. (Ejemplo: "+1 week first wednesday july 23rd, 2008" significa "2008-08-06").
  6. "ordinal nombre del día 'of' " no avanza a otro día. (Ejemplo: "first wednesday of july 23rd, 2008" significa "2008-07-02" ya que la frase específica con 'of' restablece el día del mes a '1', por lo que el '23rd' aquí se ignora).

Observe también que el "of" en "ordinal espacio nombre del día espacio 'of' " y "'last' espacio nombre del día espacio 'of' " hace algo especial.

  1. Establece el día del mes a 1.
  2. "ordinal nombre del día 'of' " no avanza a otro día. (Ejemplo: "first tuesday of july 2008" significa "2008-07-01").
  3. "ordinal nombre del día " avanza otro día. (Ejemplo: "first tuesday july 2008" significa "2008-07-08", véase también el punto 4 en la lista de arriba).
  4. "'last' nombre del día 'of' " toma el último nombre del día del mes en curso. (Ejemplo: "last wed of july 2008" significa "2008-07-30")
  5. "'last' nombre del día" toma el último nombre del día desde el día actual. (Ejemplo: "last wed july 2008" significa "2008-06-25"; "july 2008" primero establece la fecha actual a "2008-07-01" y después "last wed" retrocede al miércoles anterior, que es "2008-06-25").

Nota:

Los valores relativos al mes se calculan basándose en la longitud de los meses por los que pasan. Un ejemplo sería "+2 month 2011-11-30", el cual produciría "2012-01-30". Esto es debido a que noviembre tiene 30 días de longitud, y diciembre tiene 31 días de longitud, produciendo un total de 61 días.

Historial de cambios

Versión Descripción
5.6.23, 7.0.8 Las semanas siempre empiezan en lunes. Antes, el domingo también se consideraba como inicio de semana.
5.3.3 "first day" y "last day" se cambiaron para que se comporten como "+1 day" y "-1 day", respectivamente. Anteriormente, el comportamiento era "first day of" y "last day of".

add a note add a note

User Contributed Notes 13 notes

up
45
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
16
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
20
oguzkonya34 at gmail dot com
11 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
12
geneticdrift
12 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
5
phpnet at rudde dot org
7 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
3
chris at burnhamup dot com
10 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
-3
mike
3 years ago
in case of somone wonder 'last day of 1 month ago' is also posible (not only month names)
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".
To Top