【问题标题】:Using DateTime to produce different date strings in PHP在 PHP 中使用 DateTime 生成不同的日期字符串
【发布时间】:2021-12-18 14:08:35
【问题描述】:

这种每年生成 2 个日期字符串的方式有些丑陋

$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') ;

它有效,但对我来说似乎很笨重(因此可能效率低下)。

提出问题;如果我必须根据参考日期生成日期(这些以不同的方式以不同的形式使用)。每个日期是否需要一个对象,还是可以执行计算以从一个 DateTime 对象生成字符串?

我看到的困难是如果我使用 $obj_now->modify()` 它不再是“现在”

【问题讨论】:

  • 我认为我们达到了“自学 PHP”的上限。我不知道创建多个 DateTime 对象的含义,无论它们是否需要资源。从现在开始计算三个日期(可以从一个 DateTime 生成)和从数据库中检索的 DateTime。所以也许@José Carlos PHP 是从现在开始生成静态日期字符串的方法,尽管必须说 DateTime 对象很容易操作。因此,如果我需要 4 个 DateTime 对象,那么希望我不会占用我的内存使用量。

标签: php datetime


【解决方案1】:

Modify 更改 DateTime 对象,但不更改格式方法。以下是您可以执行以下操作的方法:

$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" }

如果不希望修改改变原始对象,可以使用DateTimeImmutable。为了得到和上面一样的结果,DateTimeImmutable 的代码是这样的:

$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);

欲了解更多信息,请参阅DateTimeImmutable vs DateTime

【讨论】:

    【解决方案2】:

    很明显,在 modify() 之后,日期时间发生了变化,不再是“现在”。 但是您可以只使用一个对象来完成您的工作,只需更改您的指令顺序:

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

    【讨论】:

      【解决方案3】:

      编辑:正如用户 IMSoP(谢谢!)所提到的,日期对象参数被修改。因此我更改了函数以使用对象的副本来防止这种情况发生。

      我更愿意为此使用一个函数。 首先你可以,但不必声明一个日期对象。其次,您在函数调用之前声明的对象不会仅仅为了获取您需要的信息而被修改。

      <?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
      
      ?>
      

      不同的方法是 DateTimeImmutable。这可以防止在使用 modify 时更改日期。

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

      你也可以在一行内结合修改和格式

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

      【讨论】:

      • 我认为你编写函数的方式有一个坏主意:很容易忘记/没有意识到它修改了传递的对象,并编写类似 $date = new DateTime('now'); $yesterday = dateGetFormatedStringModified($date, 'Y-m-d', '-1 day'); $tomorrow = dateGetFormatedStringModified($date, 'Y-m-d', '+1 day'); 的东西赢得了不要做你期望的。
      猜你喜欢
      • 1970-01-01
      • 2014-02-11
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 2017-04-27
      • 2012-03-18
      • 1970-01-01
      相关资源
      最近更新 更多