【问题标题】:what is difference between adding date in timestamp and adding dates using strtotime?在时间戳中添加日期和使用 strtotime 添加日期有什么区别?
【发布时间】:2012-10-27 19:51:52
【问题描述】:

假设我想给27-10-2012 增加一周,这样我就可以使用:

$week = 60*60*24*7;
$newdate = strtotime('27-10-2012') +$week;


或者我可以使用

$newdate = strtotime('+1 week',strtotime('27-10-2012'));


或:

$date = new DateTime('2012-10-27');
$date->add(new DateInterval('P7D'));

那么有什么区别,特别是在使用周而不是月时?

参考:-
http://www.php.net/manual/en/function.strtotime.php
http://www.php.net/manual/en/function.date.php
及其函数签名。

【问题讨论】:

  • 或者只是$newdate= strtotime('27-10-2012 +1 week');
  • 区别更多的是一年的限制,1970-2038 为timestamp。我想说,坚持DateTime。我已经发布了an answer to another question,其中简明地解释了至少一个原因...
  • 你是什么意思?结果显然是一样的,所以也许你的意思是性能?
  • @DirkMcQuickly 没有加法的结果,考虑到有 31 天 maonthes 和 28 天一个月
  • 查看您可以找到的注释中的参考文献不建议将此函数用于数学运算。最好在 PHP 5.3 及更高版本中使用 DateTime::add() 和 DateTime::sub(),或者在 PHP 5.2 中使用 DateTime::modify()。this (mktime) 可以更多由于夏令时,比简单地将一天或一个月中的秒数添加或减去时间戳更可靠。。换句话说,为了获得可靠的结果,最好使用 DateTime。

标签: php date timestamp


【解决方案1】:

从纯代码的角度来看,它们都具有相同的值:

<?php
    $week = 60*60*24*7;
    $newdate = strtotime('27-10-2012') +$week;

    echo $newdate;
    echo '<br>';

    $newdate = strtotime('+1 week',strtotime('27-10-2012'));

    echo $newdate;
    echo '<br>';

    $date = new DateTime('2012-10-27');
    $date->add(new DateInterval('P7D'));

    echo strtotime($date->format('d-m-Y'));
?>

输出:

1351900800
1351900800
1351900800

从性能的角度来看,它有点不同。

方法1重复10000次耗时0.025587s

方法2重复10.000次耗时0.12083s

方法3重复10.000次耗时0.05738s

在任何情况下,它都非常小,您无需担心。 现在,问问自己:哪一个更具可读性?

【讨论】:

  • 方法1可能是最快的,但它没有考虑到夏令时,所以在10月底的一个星期内不会工作。它也不仅仅是可读性:strtotime() 和 PHP 的其他旧日期处理函数有一些严重的缺点。 DateTime/DateInterval 类的设计是为了避免这些问题。它们也更加灵活,提供更多功能并使很多事情变得更容易。从这个示例中可能并不明显,但建议您将它们用于 PHP 中与日期相关的所有内容。
  • 确实如此。我只是提供数据。如果您的语言具有 OO 功能,则不应使用 strtotime() 之类的函数,而应使用类提供的函数。
【解决方案2】:

处理几周很容易尝试一个月 通常我会问自己这个问题.. 一个月有多少天或几周?肯定会走60*60*24*Number of days 的路线......因为每个月的每一天都不是固定的,所以你可能会觉得自己有些不准确

简单的编程错误

$newdate = time() + (60 * 60 * 24 * 28);
                                     ^-----Now you have look for num of days
var_dump(date("Y-m-d", $newdate)); //string '2012-11-24' (length=10)

$newdate = strtotime('+1 month', strtotime('27-10-2012'));
var_dump(date("Y-m-d", $newdate)); //string '2012-11-27' (length=10)

$newdate = new DateTime('2012-10-27');
$newdate->add(new DateInterval('P1M'));
var_dump($newdate->format("Y-m-d")); //string '2012-11-27' (length=10)

示例中的第 1 个选项已失效

另一方面.... PHP DOC 说

m/d/y 或 d-m-y 格式的日期通过查看各个组件之间的分隔符来消除歧义:如果分隔符是斜线 (/),则假定为美式 m/d/y;而如果分隔符是破折号 (-) 或点 (.),则假定为欧洲 d-m-y 格式。

为避免潜在的歧义,最好尽可能使用 ISO 8601 (YYYY-MM-DD) 日期或 DateTime::createFromFormat()。

我敢打赌DateTime::createFromFormat() 是处理日期最可靠的方式,因为您可以在任何时间点通过100% 确定您传递的格式

【讨论】:

  • 几个月可能很难,但即使处理几周也不容易(至少,不像听起来那么容易)——60*60*24*Number of days 方法无法接受日光考虑到储蓄,因此在 10 月底将失败一周。正如你所说,只要坚持使用DateInterval,一切都会好起来的。
【解决方案3】:

性能可能存在差异,但(除非代码处于大循环中)对开发人员而言最重要的差异将是可读性。试着想象一下自己 1 年后,当你要更新你的代码时,你会看到:

$date->add(new DateInterval('P7D'));

那边的那行说:给我的日期加上一个间隔,一个等于“P7D”的间隔......不管那是什么意思。

或者你可以看到这个:

$week = 60*60*24*7;
$newdate = strtotime('27-10-2012') +$week;

然后想,好的,我在那个日期添加了一个变量 $week。一周等于每分钟 60 秒、每小时 60 分钟、每天 24 小时和每周 7 天。对,没错。

或者你可以看到:

$newdate = strtotime('+1 week',strtotime('27-10-2012'));

然后说:$newdate 等于 27-10-2012 之后的一周... NEXT!

PHP 本身就够乱了,别让他更糊涂了。

关于性能,您可以肯定这三者之间不会有明显差异,尽管 strtotime('+1 week'...new DateInterval('P7D') 需要进行一些文本解析,因此可能会涉及到一些问题。

【讨论】:

  • 说真的,P7D 到底有多难理解??如果只是7D 会更容易吗?是的,可能,但P 是为了解析器的利益。 P7D 的语法旨在最大限度地减少文本解析开销(处理您的另一个反对意见),并使复杂的表达式成为可能。另一方面,strtotime() 具有巨大的解析开销并且能力较差。如果您是一名使用 PHP 的程序员,那么您的工作就是了解P7DDateInterval 对象的上下文中的含义。这并不难。但如果您不知道,查找起来非常容易。
  • “P 是为了解析器的利益”。 “+1周”是为了我自己的利益。 “查找起来很容易”,我敢肯定,但不查找“+1 周”更容易
【解决方案4】:

如果您谈论的是性能方面/内存使用情况,那么您的第一个示例可能是最直接的和内存意识的。话虽如此,差异很小,除非您循环访问数千个结果并解析日期,否则您不会注意到任何差异。

对象很棒,但它们确实使用更多内存,因为它们具有更多功能和能力。 DateTime 是一个很好的对象,但是当做一些简单的事情时,比如在日期上加上一周,strtotime 就足够了。例如,您可以步行到 1 个街区外的商店或乘坐豪华轿车……如果您所做的只是增加一周,这有点矫枉过正。

话虽如此,当涉及到不同位置的时区和时间时,我会尝试更频繁地使用DateTime。从这个意义上说,效果很好,而且绝对不是矫枉过正。

所有个人意见。

【讨论】:

    【解决方案5】:

    我对@pikzen(2012 年)获得的结果有点惊讶,所以我使用strtotime() 进行了自己的一些测试。我认为问题不是从正确的角度考虑的。

    如果我们要使用带有时间戳的strtotime(),则应该在进行任何操作之前从头开始转换时间戳。

    E.G.我目前正在编写一个算法,该算法会在很长一段时间内重复停电和假期,当然,需要大量的日期验证和操作。

    我使用 PHP 7 进行了 1,000,000 次重复的小测试,结果如下:

    对于必须处理大量日期操作的复杂算法,在我看来,处理整数时间戳而不是字符串 DateTimes 有一点好处。

    这是用于我的测试的代码:

    set_time_limit(180); //3 minutes
    
    echo "<style>table, tr, th, td {border-style:solid; padding:2px;}</style>" .
        "<h1>Date add using strtotime() 1,000,000 repetitions</h1>" . 
        "<table><b><tr style='background-color:LavenderBlush;'><th>Unit</th>" .
        "<th>String date with conversion</th><th>String date w/o conversion</th>" . 
        "<th>Timestamp with conversion</th><th>timestamp w/o conversion</th></tr></b>";
    
    
    //add day
    echo "<tr style='background-color:aqua;'><td><b>Day</b></td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = date('Y-m-d', strtotime($date . '+1 day'));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = strtotime($date . '+1 day');
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = date('Y-m-d', strtotime('+1 day', $date));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = strtotime('+1 day', $date);
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td><tr>";
    
    
    //add week
    echo "<tr style='background-color:LightCyan;'><td><b>Week</b></td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = date('Y-m-d', strtotime($date . '+1 week'));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = strtotime($date . '+1 week');
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = date('Y-m-d', strtotime('+1 week', $date));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = strtotime('+1 week', $date);
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td><tr>";
    
    
    //add month
    echo "<tr style='background-color:LightGreen;'><td><b>Month</b></td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = date('Y-m-d', strtotime($date . '+1 month'));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = strtotime($date . '+1 month');
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = date('Y-m-d', strtotime('+1 month', $date));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = strtotime('+1 month', $date);
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td><tr>";
    
    
    
    //add year
    echo "<tr style='background-color:LightGoldenRodYellow;'><td><b>Year</b></td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = date('Y-m-d', strtotime($date . '+1 year'));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    $date = date("Y-m-d");
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = strtotime($date . '+1 year');
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $newDate = date('Y-m-d', strtotime('+1 year', $date));
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td>";
    
    
    $date = strtotime(date("Y-m-d"));
    
    $test = microtime(true);
    
    for ($i = 0; $i < 1000000; $i++) {
    
        $date = strtotime('+1 year', $date);
    }
    
    echo "<td>" . (microtime(true) - $test) . "</td><tr></table>";
    
    
    //string date comparation 
    
    echo "<br /><h1>Date comparission with 1,000,000 repetition</h1>";
    
    
    $date = date("Y-m-d");
    
    $i = 0;
    
    $newDate = date('Y-m-d', strtotime($date . '+1 year'));
    
    $test = microtime(true);
    
    while ($i < 1000000) {
    
        if ($date !== $newDate) {
    
            $i++;
        }
    }
    
    echo "<br / ><b>String date comparission:</b> " . (microtime(true) - $test) . "<br />";
    
    
    //timestamp comparision
    
    $date = strtotime($date);
    
    $i = 0;
    
    $newDate = strtotime($newDate);
    
    $test = microtime(true);
    
    while ($i < 1000000) {
    
        if ($date !== $newDate) {
    
            $i++;
        }
    }
    
    echo "<b>timestamp comparission:</b> " . (microtime(true) - $test) . "<br />";
    

    【讨论】:

      猜你喜欢
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多