ultimo transcurrido tiempo restar obtener mostrar mes los fechas fecha entre dias actual php date

restar - tiempo transcurrido entre dos fechas php



PHP: Agregar meses a una fecha, sin exceder el último día del mes (4)

Para cualquier persona interesada, hice un enfoque sólido para tratar este problema

/** * @var /DateInterval */ private $remainder; /** * @param /DateTimeImmutable $date * @param string $modifier * @return /DateTimeImmutable */ private function nextInterval(/DateTimeImmutable $date, $modifier) { $dayNumber = (int)$date->format(''j''); $next = $date->modify($modifier); if (!is_null($this->remainder)) { $next = $next->add($this->remainder); $dayNumber += $this->remainder->days; $this->remainder = null; } // This should in general only apply to months which do not have the same daynumber in that month after adding if ($dayNumber !== (int)$next->format(''j'')) { $n = $next->modify(''last day of last month''); $this->remainder = $n->diff($next); $next = $n; } return $next; }

Resultados:

2014-11-30 2014-12-30 2015-01-30 2015-02-28 2015-03-30 2015-04-30 2015-05-30

y

2015-12-30 2016-01-30 2016-02-29 2016-03-30 2016-04-30

Buscando crear una función que hará esto en PHP.

Necesito agregar un número de meses a una fecha, pero no exceder el último día del mes para hacerlo.

Por ejemplo:

Add 1 month to January (1-28th), 2011, should produce February (1-28th), 2011. Add 1 month to January 30th, 2011, should produce February 28th, 2011. Add 3 months to January 31st, 2011, should produce April 30th, 2011. Add 13 months to January 30th, 2011, should produce February 29th, 2012. Add 1 month to October 31st, 2011, should produce November 30th, 2011.

Si utilizo la adición de fecha en PHP, obtengo excesos:

Adding 1 month to January 30th, 2011, results in March 2nd, 2011.

Mi especificación no me permite rebasarme en un nuevo mes.

¿Cuál es el método más fácil de lograr esto?


Por lo que puedo decir, este problema tiene un alcance muy limitado, por lo que es más probable que sea mejor probando un tipo de error y solucionándolo.

Todo lo que quiere hacer es asegurarse de que agregar "un mes" a una fecha tardía como el 29, 30 o 31 no lo empuje hacia adelante al 1, 2 o 3 del mes siguiente.

La forma en que funciona date_modify () (utilizándola en una fecha de ejemplo "2012-01-31" con una cadena como "+1 meses"), es que primero aumenta el número del mes en 1, luego encuentra el día 31 desde el comienzo. de ese mes. Es por eso que se extiende hasta el 3 de marzo.

Cuando esto no es lo que desea, todo lo que tiene que hacer es usar date_modify () de nuevo, ahora diciéndole que retroceda unos días (3 días en este ejemplo). Como solo desea volver al último día del mes anterior, la cantidad de días que desea volver es siempre la misma que el día del mes en su fecha incorrecta.

Lo único que queda es asegurarse de no aplicar esta corrección cuando no sea necesaria, como cuando PHP mejora en el futuro. Esto es relativamente fácil, porque el alcance de las posibles situaciones problemáticas es muy limitado.

  • (1) El problema solo ocurre al agregar meses a las fechas 29, 30 o 31
  • (2) Cuando ocurre el problema, la fecha resultante es siempre 1, 2 o 3.

Mi código a continuación agrega "+1 mes", comprueba si eso ha provocado que el día del mes cambie frenéticamente de algo alto a algo bajo, y ajusta la fecha si ese es el caso.

//Create the date, store its day-of-month, and add X months $myDateTimeISO = "2012-01-31"; $addThese = 1; $myDateTime = new DateTime($myDateTimeISO); $myDayOfMonth = date_format($myDateTime,''j''); date_modify($myDateTime,"+$addThese months"); //Find out if the day-of-month has dropped $myNewDayOfMonth = date_format($myDateTime,''j''); if ($myDayOfMonth > 28 && $myNewDayOfMonth < 4){ //If so, fix by going back the number of days that have spilled over date_modify($myDateTime,"-$myNewDayOfMonth days"); } echo date_format($myDateTime,"Y-m-d");

Resultados en: 2012-02-29 (sí, este fue un año bisiesto).

PD: si quiere agregar años, el problema y los síntomas son casi idénticos. Nuevamente, solo necesita verificar si el día del mes resultante es 1/2/3 y el día del mes entrante es el 29/30/31. Si es así, debe volver atrás "-X días" usando date_modify, donde X es el día del mes resultante.


Puede comparar el día del mes antes y después de agregar 1 mes. Si no es lo mismo, excediste el mes siguiente.

function add($date_str, $months) { $date = new DateTime($date_str); // We extract the day of the month as $start_day $start_day = $date->format(''j''); // We add 1 month to the given date $date->modify("+{$months} month"); // We extract the day of the month again so we can compare $end_day = $date->format(''j''); if ($start_day != $end_day) { // The day of the month isn''t the same anymore, so we correct the date $date->modify(''last day of last month''); } return $date; } $result = add(''2011-01-28'', 1); // 2011-02-28 $result = add(''2011-01-31'', 3); // 2011-04-30 $result = add(''2011-01-30'', 13); // 2012-02-29 $result = add(''2011-10-31'', 1); // 2011-11-30 $result = add(''2011-12-30'', 1); // 2011-02-28


esto parece funcionar para mí y te da el resultado deseado:

<?php $date = "2011-01-30"; list($year,$month,$day) = explode("-",$date); // add month here $month++; // to avoid a month-wrap, set the day to the number of days of the new month if it''s too high $day = min($day,date("t",strtotime($year."-".$month."-01"))); $date = $year."-".$month."-".$day; // 2011-02-28 echo $date; ?>

EDITAR:
Después de leer Crend Kings Comemnt, creo que necesitamos más información aquí. cuál es el resultado deseado en los siguientes casos:

2011-01-30 > 2011-02-28 2011-01-28 > 2011-02-28 or 2011-02-26 ? 2011-02-01 > 2011-03-01 or 2011-03-03 ?

en palabras: ¿debería el método agregar el número de días del mes siguiente, que es lo que hace Crend King y qué resultados como 2011-02-26 y 2011-03-03 (que no me parecen los resultados deseados? ) o debería agregar un mes y dejar el día como está, en lugar de un día que es "demasiado alto" como lo hace mi código? estoy confundido...