2010-12-05 17 views
10

Estoy tratando de averiguar el primer miércoles de un mes determinado usando strtotime, pero el argumento del "primer miércoles" falla cada vez que el primer miércoles cae en la primera.Obteniendo el primer día de la semana en un mes con strtotime

Para una ilustración más general de este problema, consulte el siguiente código y resultado:

$mon = strtotime("December 2010 first monday"); 
$tue = strtotime("December 2010 first tuesday"); 
$wed = strtotime("December 2010 first wednesday"); 
$thu = strtotime("December 2010 first thursday"); 
$fri = strtotime("December 2010 first friday"); 
$sat = strtotime("December 2010 first saturday"); 
$sun = strtotime("December 2010 first sunday"); 

echo strftime("%m/%d/%y", $mon) . "<br>"; 
echo strftime("%m/%d/%y", $tue) . "<br>"; 
echo strftime("%m/%d/%y", $wed) . "<br>"; 
echo strftime("%m/%d/%y", $thu) . "<br>"; 
echo strftime("%m/%d/%y", $fri) . "<br>"; 
echo strftime("%m/%d/%y", $sat) . "<br>"; 
echo strftime("%m/%d/%y", $sun) . "<br>"; 

Resultados en:

12/06/10 
12/07/10 
12/08/10 
12/02/10 
12/03/10 
12/04/10 
12/05/10 

Aviso algo? ¿No debería un día de la semana coincidir con el 1 ° del mes? Pero nunca lo hace, y en su lugar, la segunda instancia del día, el día 8, siempre se devuelve.

¿Alguien tiene una explicación para esto?

Respuesta

8

no tengo ninguna explicación También estoy deslumbrado, pero me las arreglé para averiguar cómo obtener la fecha correcta omitiendo la "primera", así:

$ php -r 'echo date("m/d/y", strtotime("December 2010 Wednesday"));' 
12/01/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));' 
12/02/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));' 
12/03/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));' 
12/04/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));' 
12/05/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));' 
12/06/10 

$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));' 
12/07/10 
+0

por supuesto, esto funciona. No preguntemos por qué ... – Yarin

+0

Bueno, podrías mirar el código fuente de php si eres realmente curioso, en cuanto a mí, sigamos adelante: D –

+0

Parece que no funciona del todo. Estoy utilizando esta solución el 12 de junio y recibo '12/15/2014'. Tal vez es relativo a la semana del mes en que se encuentra actualmente? – Webnet

5

Es sólo su formateo que es incorrecto Es necesario incluir of:

echo strftime("%m/%d/%y", strtotime("first Monday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Tuesday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Wednesday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Thursday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Friday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Saturday of December 2010")); 
echo strftime("%m/%d/%y", strtotime("first Sunday of December 2010")); 

Lienzo:

12/06/10 
12/07/10 
12/01/10 
12/02/10 
12/03/10 
12/04/10 
12/05/10 

funciona de la solución aceptada, pero sería encontrar problemas si quieres encontrar el segundo día de la semana:

echo strftime("%m/%d/%y", strtotime("December 2010 second Wednesday")); 

Prints:

12/15/10 

Hay algunos ejemplos que figuran en los documentos:

http://www.php.net/manual/en/datetime.formats.relative.php

El segundo bloque de notas en la documentación anterior explica cómo of afecta el proceso de cálculo de la fecha:

también observan que el "de "en" ordinal space dayname space 'of' "y" 'last' space dayname space 'of' "hace algo especial.

  1. Se establece el día de mes a 1.
  2. "ordinal nombre 'de'" no avanza a otro día. (Ejemplo: "primer martes de julio de 2008" significa "2008-07-01").
  3. "ordinal dayname" avanza a otro día. (Ejemplo: "primer martes de julio de 2008" significa "2008-07-08", ver también el punto 4 en la lista anterior).
  4. "'last' dayname 'of'" toma el último nombre del día del mes actual. (Ejemplo: "el último mes de julio de 2008" significa "2008-07-30")
  5. "'last' dayname" toma el apellido pasado del día actual. (Ejemplo: "el último miércoles de julio de 2008" significa "2008-06-25"; "julio de 2008" establece por primera vez la fecha actual como "2008-07-01" y y luego "último wed" se mueve al anterior Miércoles que es "2008-06-25").
+1

el formato 'de' solo funciona en PHP> = 5.3 y falla en 5.2. Ver mi respuesta para los resultados de las pruebas. – Yarin

+1

@Yarin: Bien manchado. La fecha de manejo en> = 5.3 parece ser mucho más confiable que las versiones anteriores. Es una pena que haya tantas trampas potenciales. – Mike

10

La construcción de las respuestas proporcionadas, uno tiene que ser consciente de las diferencias en el formato de fecha relativa entre PHP 5.2 y PHP 5.3.

PRUEBA:

$date1 = strtotime("first wednesday of 2010-12"); 
$date2 = strtotime("first wednesday 2010-12"); 
$date3 = strtotime("wednesday 2010-12"); 

5,2 Resultados:

1969-12-31 
2010-12-08 
2010-12-01 

5.3 Resultados:

2010-12-01 
2010-12-08 
2010-12-01 

Por tanto, sólo º El tercer método arroja resultados correctos en las versiones de PHP 5.

1

Encontré esta nota en el manual de PHP.

"En PHP 5 anterior a 5.2.7, solicitar una ocurrencia dada de un día de la semana determinado en un mes en el que ese día era el primer día del mes agregaría incorrectamente una semana a la marca de tiempo devuelta. Esto se corrigió en 5.2.7 y versiones posteriores ".

0

PHP 5.5.11

$firstWeekdayOfMonth = new DateTime('first weekday 0 jun 2016');

no sé por qué, pero el tipo de fuerza cero el analizador strtotime a empezar por el principio del mes teniendo en cuenta el primer día.

Cuestiones relacionadas