1

suppose i want to add one week to 27-10-2012 so i can use:

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


or i can use

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


or:

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

so what is the differences especially when using weeks not monthes ?

referances:-
http://www.php.net/manual/en/function.strtotime.php
http://www.php.net/manual/en/function.date.php
and their function signatures.

Mostafa Darwish
  • 273
  • 1
  • 4
  • 14
  • Or just `$newdate= strtotime('27-10-2012 +1 week');` – Tim Withers Oct 27 '12 at 19:58
  • The difference is more the limitation for the year, 1970-2038 for `timestamp`. I'd say, stick to `DateTime`. I've posted [an answer to another question](http://stackoverflow.com/questions/12909463/issue-with-php-mktime-and-or-php-date-years-prior-to-1901-64-bit/12909524#12909524) in which is concisely explained at least one reason why... – Havelock Oct 27 '12 at 19:59
  • what sort of difference do you mean? The result is obviously the same, so maybe you mean performance? – Dirk McQuickly Oct 27 '12 at 20:00
  • @DirkMcQuickly no the result of addition consider that there is 31 day maonthes and 28 days month – Mostafa Darwish Oct 27 '12 at 20:02
  • 1
    Look at your references in the notes you can find **Using this function for mathematical operations is not advisable. It is better to use DateTime::add() and DateTime::sub() in PHP 5.3 and later, or DateTime::modify() in PHP 5.2.** and **This (mktime) can be more reliable than simply adding or subtracting the number of seconds in a day or month to a timestamp because of daylight saving time.** . In other words for reliable result it's better to use DateTime. – Marcin Szulc Oct 27 '12 at 20:11

5 Answers5

1

From a pure code standpoint, they all have the same value:

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

Output:

1351900800
1351900800
1351900800

From a performance standpoint, it's a bit different.

Method 1 repeated 10.000 times takes 0.025587s

Method 2 repeated 10.000 times takes 0.12083s

Method 3 repeated 10.000 times takes 0.05738s

In every case, it's so minimal you don't need to worry about it. Now, ask yourself : which one is more readable ?

pikzen
  • 1,413
  • 1
  • 10
  • 18
  • Method 1 may be the quickest, but it's fails to take daylight saving into account, so won't work for a week at the end of October. And it's not just about readability either: `strtotime()` and PHP's other old date handling functions have some severe shortcomings. The DateTime/DateInterval classes have been designed with the benefit of hindsight to avoid those issues. They're also much more flexible, provide more functionality and make a lot of things a lot easier. It may not be obvious from this one example, but you would be well advised to use them for everything date related in PHP. – Spudley Oct 27 '12 at 20:36
  • Indeed. I was just providing data. If you've got a language with OO capabilities, you shouldn't use functions like strtotime() but the class-provided ones. – pikzen Oct 27 '12 at 23:12
0

There might be differences in performance, but (unless that code is in a big loop) the most important difference for you, the developer, will be readability. Try imagine yourself 1 year from now when you are up to update your code and you see this:

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

That line over there says: Add an interval to my date, an interval equal to 'P7D'... whatever that means.

Or you could see this:

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

and think, ok I'm adding a variable $week to that date. A week is equal to 60 seconds per minute, 60 minutes per hour, 24 hours per day and 7 days per week. Yep, that's right.

Or you could see:

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

and say: $newdate is equal to a week after 27-10-2012... NEXT!

PHP can be enough of a mess by itself, don't help him to be an more confusing.

And about performance, you can be sure there won't be mayor differences between those three, although strtotime('+1 week'... and new DateInterval('P7D') need to do some text parsing, so some ticks might go into that.

whtlnv
  • 2,109
  • 1
  • 25
  • 26
  • Seriously, just how hard is `P7D` to understand?? Would it be easier if it was just `7D`? Yes, probably, but the `P` is there for the benefit of the parser. The syntax of `P7D` has been designed to minimise the text parsing overhead (which deals with another of your objections) and also to make complex expressions possible. `strtotime()` on the other hand has a massive parsing overhead and is less capable. If you're a programmer working with PHP, it's your job to know what `P7D` means in the context of `DateInterval` object. It's not hard. But if you don't know, it's very easy to look it up. – Spudley Oct 27 '12 at 20:30
  • 1
    "the P is there for the benefit of the parser". '+1 week' is there for my own benefit. "it's very easy to look it up", Im sure it is, but its easier to NOT look up '+1 week' – whtlnv Oct 27 '12 at 20:37
0

If you are talking performance wise/memory usage, your first example may be the most straight forward and memory conscious. That being said, the difference is MINOR, and unless you are looping through thousands of results and parsing dates, you won't notice any difference.

Objects are great, but they do use more memory as they have more functions and capabilities. DateTime is a great object to use, but when doing something simple like adding a week to a date, strtotime will be enough. Example, you can walk to the store 1 block away or take a limo... one is a bit overkill if all you are doing is adding a week.

That being said, I try to use DateTime more often when it comes to timezones and times at different locations. Works great in that sense and is definitely not overkill for that.

All personal opinion.

Tim Withers
  • 12,072
  • 5
  • 43
  • 67
0

Dealing with weeks is easy try month Typically i ask my self this question .. how many days or weeks in a month ??? definitely going the route of 60*60*24*Number of days .... since each days of the month is not fixed then you might fine your self have some inaccuracy

Simple Programing Mistakes

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

From the Example number 1 options is out

On the other note .... PHP DOC Says

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.

To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or DateTime::createFromFormat() when possible.

I would bet on DateTime::createFromFormat() to be the most reliable way of dealing with dates because you are 100% sure of the format you are passing at any point in time

Community
  • 1
  • 1
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 1
    Months may be hard, but even dealing with weeks is *not* easy (at least, not as easy as it sounds) -- the `60*60*24*Number of days` method fails to take daylight savings into account, so will fail for a week at the end of October. As you say, just stick with `DateInterval` for everything, and you'll be fine. – Spudley Oct 27 '12 at 20:39
0

I was a little bit surprised by the results obtained by @pikzen (in 2012), so I performed some test of my own using strtotime(). I think the problem wasn't thought from the right perspective.

If we are to use strtotime() with a timestamp, the timestamp should be converted from the start before doing any operations.

E.G. I'm currently writing an algorithm that creates repeated blackouts and holidays over a large period and, of course, needs a lot of date validations and operations.

I ran a little test with 1,000,000 repetitions using PHP 7 and here are my results:

Date add tests results

For a complex algorithm that has to deal with a lot of date operations, it seems to me that there's a slight benefit for dealing with integer timestamps rather than string DateTimes.

Here's the code used for my tests:

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 />";