2012-03-16 13 views
39

Estoy buscando la mejor manera de obtener el primer y último día del último mes. Los uso para hacer consultas SQL para obtener estadísticas del mes pasado.¿Cuál es la mejor manera de obtener el primer y el último día del mes pasado?

Creo que esta es la mejor manera, más optimizada pero no más comprensiva, ¿alguien tiene otra manera de hacer lo mismo?

$month_ini = date("Y-m-d", mktime(0, 0, 0, date("m", strtotime("-1 month")), 1, date("Y", strtotime("-1 month")))); 

    $month_end = date("Y-m-d", mktime(0, 0, 0, date("m", strtotime("-1 month")), date("t", strtotime("-1 month")), date("Y", strtotime("-1 month")))); 

Thanks !!

+0

posible duplicado de [PHP último día del mes] (http: // stackoverflow.com/questions/1686724/php-last-day-of-the-month) – DaveRandom

+0

¿Has probado strtotime? –

+0

http://stackoverflow.com/questions/2680501/how-can-i-find-the-first-and-last-date-in-a-month-using-php –

Respuesta

95

En PHP 5.3, se puede utilizar la clase DateTime:

<?php 

$month_ini = new DateTime("first day of last month"); 
$month_end = new DateTime("last day of last month"); 

echo $month_ini->format('Y-m-d'); // 2012-02-01 
echo $month_end->format('Y-m-d'); // 2012-02-29 
+1

Esta debería ser la respuesta imho – LeonardChallis

+3

Esto también funciona brillantemente con 'strtotime()' si quieres una marca de tiempo. Como 'strtotime ('último día del último mes')'. –

+0

¿Cómo harías esto si quisieras que el primer/último día del mes cayera alguna fecha? – Czechnology

0

se puede hacer esto en MySQL:

WHERE `DateAndTime` >= '2012-02-01 00:00:00' 
AND `DateAndTime` < '2012-03-01 00:00:00' 
+0

Gracias pero es más lento hacer esto en mysql :(gracias, necesito la optimización – aaronroman

+0

poner un índice en la columna 'DateAndTime'. dice que no obtendrá más rápido que eso. – Bazzz

3

Si usted está haciendo esto con el propósito de una consulta MySQL, ¿ha considerado el uso de la MONTH function, por ejemplo,

SELECT [whatever stats you're after] FROM table 
WHERE MONTH(date_field) = 12 and YEAR(date_field) = 2011 

Esto obtendría sus estadísticas para diciembre. Si comienza a experimentar problemas de rendimiento y los datos históricos no cambian, es posible que desee desnormalizar los datos en una tabla agregada (acumulada por el incremento más pequeño que necesita, por ejemplo, por día/por hora/mensual, etc.).

+0

y ¿qué pasa si hay filas desde diciembre de 2010 y desde diciembre de 2011? ¿Cómo se distinguen? – Bazzz

+0

@Bazzz Doh! Buen lugar, se le ha agregado el filtro equivalente de AÑO (aunque ¡Si siguieras el enlace que proporcioné, esto debería haber sido bastante obvio!) – liquorvicar

55

Último día del mes anterior:

date("Y-m-d", mktime(0, 0, 0, date("m"), 0)); 

primer día del mes anterior:

date("Y-m-d", mktime(0, 0, 0, date("m")-1, 1)); 
+3

Buena respuesta; si el mes actual es 01 (enero), la fecha() disminuirá el año en uno y ajustará el mes en 12, funciona muy bien. ¡Gracias! – jwbensley

+0

Esto ayudó mucho, sin embargo, no hay explicación o enlace a la explicación de POR QUÉ funcionó. es decir. el 0 en la primera declaración es el último día porque ... (0 effectivly significa -1 ya que no hay 0 días en ningún mes y PHP lo toma como el 1º - 1) – Tarquin

-1

deja que mysql se ocupe de las fechas.

cualquier cosa que sea para que la base de datos haga, deja que lo haga.

así:

mysql_query("set @last_day=last_day(now()-interval 1 month),@first_day=(@last_day-interval 1 month)+interval 1 day"); 
$result=mysql_query("select * from `table` where (`date` between @first_day and @last_day)"); 

lo mejor es que esto va a funcionar incluso si los cambios año.

simplemente recuerde cambiar la base de datos de la zona horaria para que coincida con php.

3

Puedo utilizar estas en MySQL y PHP scripts, cortas y simples:

echo date('Y-m-d', strtotime('first day of last month')); 
echo date('Y-m-d', strtotime('last day of last month')); 

MySQL utilizar ejemplo:

$query = $db->query("SELECT * FROM mytable WHERE 1 AND mydate >= '".date('Y-m-d', strtotime('first day of last month'))."'"); 
Cuestiones relacionadas