Home > Net >  Using DateTime to produce different date strings in PHP
Using DateTime to produce different date strings in PHP

Time:11-05

There's something ugly about this way of producing 2 date strings a year apart

$obj_now = new DateTime();
$obj_year_ago = new DateTime();
$obj_year_ago->modify( '- 1 year');
$string_now = $obj_now->format('Y-m-d') ;
$string_year_ago = $obj_year_ago->format('Y-m-d') ;

It works but seems a clunky to me (and therefore probably inefficient).

To frame the question; if I have to produce dates based on a reference date (these are used in different ways in different forms). Do I need one object to each date or can I perform calculations to produce my strings from one DateTime object?

The difficulty I see is if I use $obj_now->modify()` it's no longer 'now'

CodePudding user response:

Modify changes the DateTime object, but not the format method. Here's how you can do the following:

$curDate = new DateTime('Now');
$dates = [];
for($i=0;$i<3;$i  ){
  $dates[] = $curDate->format('Y-m-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" }

If you don't want the modify to change the original object, you can use DateTimeImmutable. To get the same result as above, the code for DateTimeImmutable is like this:

$date = new DateTimeImmutable('Now');
$dates = [];
for($i=0;$i<3;$i  ){
  $curDate = $date->modify('-'.$i.' year');
  $dates[] = $curDate->format('Y-m-d');
}
var_dump($dates);

For more information see DateTimeImmutable vs DateTime

CodePudding user response:

Obviously, after modify() the datetime has changed and it's no longer 'now'. But you can do your job using just one object simply changing your instructions order:

$obj = new DateTime();
$string_now = $obj->format('Y-m-d');
$obj->modify('- 1 year');    
$string_year_ago = $obj->format('Y-m-d');

CodePudding user response:

Edit: As mentioned by the user IMSoP (Thank you!) the date object parameter gets modified. Therefore I changed the function to use a copy of the object to prevent this.

I would prefere to use a function for it. First of all you can, but not have to declare an date object. Second, the object you declared before the function calls doesn't get modified only to get the information you need.

<?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(), 'Y-m-d', '- 1 year');
$string_now = dateGetFormatedStringModified(new DateTime(), 'Y-m-d');

echo $string_now; // 2021-11-04
echo $string_year_ago; // 2020-11-04

?>

Different approach would be DateTimeImmutable. This prevents the date getting changed if modify is used.

$date = new DateTimeImmutable();
$date_last_year = $date->modify('-1 year');
echo $date->format('Y-m-d');
echo $date_last_year->format('Y-m-d');

You also can combine modify with format within one line

$date = new DateTimeImmutable();
echo $date->format('Y-m-d');
echo $date->modify('-1 year')->format('Y-m-d');
  • Related