【问题标题】:PHP datetime add 6 months and 1 yearPHP datetime 添加 6 个月和 1 年
【发布时间】:2018-01-11 12:48:56
【问题描述】:

我有一个像这样使用 PHP 日期时间设置的日期..

$originaldate = 2019-01-10 17:52:17
$converted = DateTime::createFromFormat("Y-m-d H:i:s", $originaldate);

日期已成功转换为 PHP DateTime 对象,现在我正在尝试添加 2 个新日期,分别比该日期早 6 个月和 1 年。

实现这一目标的最佳方法是什么?

【问题讨论】:

  • 您可以尝试使用 Carbon。 carbon.nesbot.com/docs/ 它非常有用且易于阅读。

标签: php datetime


【解决方案1】:

你应该看看 php 类 DateInterval http://php.net/manual/en/class.dateinterval.php

这是一个例子:

$converted = DateTime::createFromFormat("Y-m-d H:i:s", $originaldate); 
$converted1Year = $converted->add(new DateInterval("P1Y"));//add one year //object reference is the same so adding a year altered original object and a reference to it is passed back, not copied
$converted2 = DateTime::createFromFormat("Y-m-d H:i:s", $originaldate);
$converted6months = $converted2->add(new DateInterval("P6M")); // add 6 months

正如 cmets 中所建议的,这里是 DateTimeImmutable 等效项:

$converted = DateTimeImmutable::createFromFormat("Y-m-d H:i:s", $originaldate); 
$converted1Year = $converted->add(new DateInterval("P1Y"));
$converted6Months = $converted->add(new DateInterval("P6M"));

【讨论】:

  • 这不起作用 - 请注意,每次调用 add 都会修改 $converted 并返回它,而不仅仅是返回一个新对象。所以$sixmonthsahead 实际上提前了 18 个月,因为该对象已经添加了一年。如果你改用DateTimeImmutable,就可以避免这个问题。
  • @user3647971:您可以找到比启动两次相同对象更好的解决方案。例如,您可以使用DateTimeImmutable 类。
【解决方案2】:

您可以在clone 的时间创建一个副本并使用DateTime::modify 更改新的日期。

试试这个;

$sixMonths = clone $converted;
$sixMonths->modify('+6 months');

$oneYear = clone $converted;
$oneYear->modify('+1 year');

【讨论】:

  • @DeniseMeander 是的 clone 是一部分 PHP
  • 这个方法比使用 DateTime::add 有什么好处吗?
  • @fightstarr20 DateTime::modify 采用人类可读的字符串,DateTime::add 采用 DateInterval 对象,该对象使用 ISO-8601 格式字符串。不过,完全取决于您自己的喜好。
【解决方案3】:

查看DateTime::add

$converted->add(new DateInterval("P18M")); // add 18 months

P18M 表示 18 个月间隔

【讨论】:

    【解决方案4】:

    像这样:

       $sixMonths = date('Y-m-d', strtotime($converted. ' + 6 months'));
       $oneYear = date('Y-m-d', strtotime($converted. ' + 1 year'));
    

    【讨论】:

    • 如果$convertedDateTime 对象,这将不起作用,对吗?
    • 当提出问题的人已经开始使用更复杂的 DateTime 对象时,基于简单的基于 unix-timestamp 的函数(如 date() 和 strtotime())给出答案很少是好的建议
    【解决方案5】:
    $converted = $converted->modify('+6 months');
    $converted = $converted->modify('+1 year');
    

    【讨论】:

    • 这个建议是 Memduh 提前 4 小时给出的。这个无法解释的答案没有给这个页面增加新的价值。
    【解决方案6】:

    格式已经默认("Y-m-d H:i:s")。您不需要使用 CreateFromFormat,除非您处理来自第 3 方的数据。我对代码的建议是这样的

    $originaldate = '2019-01-10 17:52:17';
    $converted = new DateTime( $originaldate ); //prefer like this
    //DateTime::createFromFormat("Y-m-d H:i:s", $originaldate); //after browsing this is recomended
    
    $date6Month = new DateTime( $originaldate );
    $date1Year = new DateTime( $originaldate );
    $dateBack = new DateTime( $originaldate );
    //$date6Month = $date1Year = $dateBack= $converted;
    //prefer to use different variable for every date. Not copy
    
    echo "ori:".$converted ->format('Y-m-d H:i:s') . "\n"; 
    //ori:2019-01-10 17:52:17
    
    ##6 month later
    $date6Month ->add(new DateInterval('P6M'));
    echo "6 month:".$date6Month ->format('Y-m-d H:i:s') . "\n";
    //6 month:2019-07-10 17:52:17
    
    ##1 year later
    $date1Year ->add(new DateInterval('P1Y'));
    echo "1 year:".$date1Year ->format('Y-m-d H:i:s') . "\n";
    //1 year:2020-01-10 17:52:17
    //1 year:2020-07-10 17:52:17 (wrong if using copy main parameter)
    
    $date1Year ->add(  DateInterval::createFromDateString('1 Years') );
    echo "1 year (later):".$date1Year ->format('Y-m-d H:i:s') . "\n";
    //1 year (later):2021-01-10 17:52:17
    //1 year (later):2021-07-10 17:52:17 (wrong if using copy main parameter)
    

    您可以将 DateInterval::createFromDateString 用于可读代码,而不是使用格式。我的建议是将变量而不是从源中复制。

    可以在 DateInterval 上使用的格式

    当包含日、月和年时以“P”开头

    Format Info Example
    Y Year 1Y
    M Month 3M
    D Day 5D

    示例:P1Y3M5D

    如果不包含日、月和年 (PT1H),则始终在“T”之前开始“P”。如果不以“T”开头

    Format Info Example
    H HOUR 1H
    M MINUTES 3M
    S SECONDS 5S
    F MICROSECOND (php7+) 5F

    示例:PT1H3M5S

    错误:T1H3M5S

    其他示例(来自下面的链接)

    date_default_timezone_set('America/Phoenix'); 
    //is important to add when your time are detail
    $date = new DateTime('2000-01-01');
    $date->add(new DateInterval('P7Y5M4DT4H3M2S'));
    echo $date->format('Y-m-d H:i:s') . "\n";
    //2007-06-05 04:03:02
    
    $originaldate = 2019-01-10 17:52:17
    $dateBack = $dateBack2 = new DateTime( $originaldate );
    //if you want to substract the value you can use this
    $dateBack ->sub(new DateInterval('P1Y2M3DT1H4M1S'));
    echo $dateBack ->format('Y-m-d H:i:s') . "\n";
    //output: 2019-05-07 16:48:16
    
    $dateBack2=$converted;
    $formatDay='P1Y3M6D'; //only year, month and day 
    $formatTime='T1H3M6S'; //only hour, minutes and seconds
    $dateBack2 ->sub(new DateInterval( $formatDay.$formatTime ));
    echo $dateBack ->format('Y-m-d H:i:s') . "\n";
    //2018-02-01 15:45:10
    
    

    如 phpmanual 中所述,此示例中未包含其他格式(微时间)。

    相关链接

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 1970-01-01
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多