Hay algo feo en esta forma de producir 2 cadenas de fechas con un año de diferencia
$obj_now = new DateTime(); $obj_year_ago = new DateTime(); $obj_year_ago->modify( '- 1 year'); $string_now = $obj_now->format('Ym-d') ; $string_year_ago = $obj_year_ago->format('Ym-d') ;Funciona, pero me parece un poco torpe (y, por lo tanto, probablemente ineficiente).
Para enmarcar la pregunta; si tengo que producir fechas basadas en una fecha de referencia (estas se usan de diferentes maneras en diferentes formas). ¿Necesito un objeto para cada fecha o puedo realizar cálculos para producir mis cadenas a partir de un objeto DateTime?
La dificultad que veo es que si uso $obj_now ->modify()` ya no es 'ahora'
Modificar cambia el objeto DateTime, pero no el método de formato. Así es como puede hacer lo siguiente:
$curDate = new DateTime('Now'); $dates = []; for($i=0;$i<3;$i++){ $dates[] = $curDate->format('Ym-d'); $curDate->modify('-1 year'); } var_dump($dates); //array(3) { [0]=> string(10) "2021-11-04" [1]=> string(10) "2020-11-04" [2]=> string(10) "2019-11-04" }Si no desea que la modificación cambie el objeto original, puede usar DateTimeImmutable . Para obtener el mismo resultado que el anterior, el código para DateTimeImmutable es así:
$date = new DateTimeImmutable('Now'); $dates = []; for($i=0;$i<3;$i++){ $curDate = $date->modify('-'.$i.' year'); $dates[] = $curDate->format('Ym-d'); } var_dump($dates);Para obtener más información, consulte DateTimeImmutable vs DateTime
Obviamente, después de modificar (), la fecha y hora ha cambiado y ya no es 'ahora'. Pero puede hacer su trabajo usando solo un objeto simplemente cambiando el orden de sus instrucciones:
$obj = new DateTime(); $string_now = $obj->format('Ym-d'); $obj->modify('- 1 year'); $string_year_ago = $obj->format('Ym-d');Editar: como lo mencionó el usuario IMSoP (¡Gracias!), el parámetro del objeto de fecha se modifica. Por lo tanto, cambié la función para usar una copia del objeto para evitar esto.
Preferiría usar una función para ello. En primer lugar, puede, pero no tiene que declarar un objeto de fecha. En segundo lugar, el objeto que declaró antes de que la función llame no se modifica solo para obtener la información que necesita.
<?php /** * @param DateTime $dt_date * @param String $s_format * @param String $s_modifier * @return String */ function dateGetFormatedStringModified($dt_date, $s_format, $s_modifier = ''){ $dt_temp = clone $dt_date; if(!empty($s_modifier)){ $dt_temp->modify($s_modifier); } return $dt_temp->format($s_format); } $string_year_ago = dateGetFormatedStringModified(new DateTime(), 'Ym-d', '- 1 year'); $string_now = dateGetFormatedStringModified(new DateTime(), 'Ym-d'); echo $string_now; // 2021-11-04 echo $string_year_ago; // 2020-11-04 ?>Un enfoque diferente sería DateTimeImmutable. Esto evita que se cambie la fecha si se usa modificar.
$date = new DateTimeImmutable(); $date_last_year = $date->modify('-1 year'); echo $date->format('Ym-d'); echo $date_last_year->format('Ym-d');También puede combinar modificar con formato dentro de una línea
$date = new DateTimeImmutable(); echo $date->format('Ym-d'); echo $date->modify('-1 year')->format('Ym-d');