Pregunta

Esto funcionó bien ayer sin cambios en el código.

echo date("M", strtotime("-3 month", time()) );
echo date("M", strtotime("-2 month", time()) );
echo date("M", strtotime("-1 month", time()) );
echo date("M", time());

La producción que estaba produciendo ayer fue la esperada, es decir, abril, mayo, junio, julio

Hoy hace eco mayo mayo julio julio

¿Alguna idea?

Gracias de antemano.

¿Fue útil?

Solución

Podría estar relacionado con el error # 44073

Podrías probar con algo como esto:

echo date("M", strtotime("-3 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-2 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", strtotime("-1 month", strtotime(date("F") . "1")) ) . "\n";
echo date("M", time()) . "\n";

(Solución encontrada en la sección de comentarios de strtotime ; enlace directo )

Y la salida:

Apr
May
Jun
Jul

Tipo de "trampa" con el formato de fecha y el nombre del mes y todo eso ...

Otros consejos

Gorden identificó correctamente el problema, pero quería dar otra solución que fuera útil y no tan técnica. Solo use " primer día de " o "último día de" en tu tiempo de trabajo. Por ejemplo, los siguientes ejemplos resuelven el problema el día 31 de un mes:

// Today is May 31st
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d'); 

// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month")); 
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');

Pruebe esto en lugar de strtotime :

mktime(0, (date("n") - 3 + 12) % 12, 1)

La idea es tomar el número del mes actual ( fecha (" n ") ), restar el número de meses que desee (aquí -3 ) , agregue 12 y luego obtenga el módulo 12.

Este es un comportamiento conocido y esperado. La razón de esto es que un mes es una fecha relativa sin duración fija. De http: // www. gnu.org/software/tar/manual/html_node/Relative-items-in-date-strings.html#SEC120

  

La unidad de desplazamiento de tiempo puede seleccionarse mediante la cadena ‘año’ o ‘mes’ para desplazarse por años o meses enteros. Estas son unidades difusas, ya que los años y los meses no tienen la misma duración. Las unidades más precisas son 'quincena' que vale 14 días, 'semana' vale 7 días, 'día' vale 24 horas, 'hora' vale 60 minutos, 'minuto' o 'min' vale 60 segundos y 'segundo' o 'segundo' vale un segundo. Se acepta e ignora el sufijo 's' en estas unidades.

Consecuentemente (énfasis mío)

  

El fuzz en unidades puede causar problemas con elementos relativos. Por ejemplo, "2003-07-31 -1 mes" podría evaluarse a 2003-07-01, porque 2003-06-31 es una fecha no válida. Para determinar el mes anterior de manera más confiable, puede solicitar el mes anterior al 15 del mes actual . Por ejemplo:

$ date -R
Thu, 31 Jul 2003 13:02:39 -0700
$ date --date='-1 month' +'Last month was %B?'
Last month was July?
$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
Last month was June!

Lo anterior podría expresarse en PHP como

echo date('M', strtotime(date('Y-m-') . '15 -1 month'));

Consulte también los comentarios a continuación http://bugs.php.net/bug.php ? id = 22486

Desde PHP 5.3 (Ref: https://bugs.php.net/bug. php? id = 44073 ) y superior que puedes hacer:

" primer día de +1 mes " o " primer día del próximo mes " o incluso " último día del próximo mes "

Ejemplo:

$date = '2015-12-31';

echo date("Y-m-d", strtotime($date ."first day of previous month"));

Producirá: 2015-11-01 Esto no calcula días en más de 30 días.

una forma simple podría ser escribirlo así

echo date (" M " ;, strtotime (" este año +3 meses "));

o

echo date (" M " ;, strtotime (" este mes -3 meses "));

depende para qué lo estés usando ..

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top