views:

285

answers:

8

I am pulling a datetime from a mysql db and i would like to add X hours to it then compare it to the current time. So far i got

$dateNow = strtotime(date('Y-m-d H:i:s'));
$dbTime = strtotime($row[0]);

then i tried $dbTime + strtotime("4 hours"); but 4 hours seem to add 4hrs to the current time instead of raw 4hours. How do i add X hours to dbTime?

NOTE: I am using php 5.1.2 so date_add doesnt work (5.3.0)

A: 

I tend to use the time() function, and this page from the manual shows them displaying the date a week in the future: http://us3.php.net/manual/en/function.time.php

James Black
A: 

Here's how I'd do it:

  1. Pull the time from the database using the UNIX_TIMESTAMP() function.

  2. The UNIX timestamp is in seconds, so add 4*60*60 to it.

  3. Convert the modified UNIX timestamp to a date using PHP's localtime() or strftime() function.

    query("SELECT UNIX_TIMESTAMP(someDatetimeColumn) ...");
    . . .
    $dbTimeAdjusted = localtime($row[0] + 4*60*60);
    
Bill Karwin
+1  A: 

time() and strtotime() result in unix timestamps in seconds, so you can do something like the following, provided your db and do your comparison:

$fourHours = 60 * 60 * 4;
$futureTime = time() + $fourHours;
sparkey0
+3  A: 

then i tried $dbTime + strtotime("4 hours"); but 4 hours seem to add 4hrs to the current time instead of raw 4hours. How do i add X hours to dbTime?

strtotime has an optional second argument. Provide a Unix timestamp there and the output will be relative to that date instead of the current date.

$newTime = strtotime('+4 hours', $dbTime);

You can also use the fact that Unix timestamps are seconds-based - if you know what four hours are in seconds, you can just add that to the time integer value.

ceejayoz
DON'T just add seconds to a unixtime! That is the start of a slippery slope of doing all time/date manipulations like that and that is horribly difficult to maintain and keep debugged, particularly with timezones and daylight-saving to consider. There are library functions that get all the difficult corner and edge cases correct.
staticsan
DO just add seconds to a unixtime! That's what it was made for, obviously.
Robert L
@staticsan, adding seconds onto a unix timestamp is perfectly acceptable. It is a measure of seconds since an epoch date, and no amount of timezone changes or daylight savings time will affect it. TZs and DST will affect the human-readable version, but the timestamp is unaffected.
nickf
It rather depends on the context of the original timestamp and why it is being compared to "now", neither of which we have. If it is a straightforward shift of X hours and that shift makes sense in the algorithm, then just adding seconds to the unix timestamp makes sense. Unfortunately I have seen too much code that does that even when it doesn't make sense or isn't clear and had to fix the resulting bugs.
staticsan
if you want to find out what the current time is in a different timezone, then no, you should never add/subtract seconds. if you want to find what the time will be in 4 hours, then timestamp arithmetic is the perfect solution.
nickf
+3  A: 

You have quite a few options here:

1.

$result = mysql_query("SELECT myDate FROM table");
$myDate = mysql_result($result, 0);
$fourHoursAhead = strtotime("+4 hours", strtotime($myDate));

2.

// same first two lines from above
$fourHoursAhead = strtotime($myDate) + 4 * 60 * 60;

3.

$result = mysql_query("SELECT UNIX_TIMESTAMP(myDate) FROM table");
$myDate = mysql_result($result, 0);
$fourHoursAhead = $myDate + 4 * 60 * 60;

4.

$fourHoursAhead = strtotime("+4 hours", $myDate);

5.

$result = mysql_query("SELECT UNIX_TIMESTAMP(DATE_ADD(myDate, INTERVAL 4 HOUR))");
$fourHoursAhead = mysql_result($result, 0);
nickf
If I could downvote a part of your question, I would. #2 is the worst solution you could have posted.
staticsan
really? I would have thought #1 was the worst. For the record, personally I'd probably use either #3 or #5, depending on how much control I have over building the SQL query.
nickf
See the comments to ceejayoz's answer for why I think so.
staticsan
+1  A: 

strtotime("+4 hours", $dbTime);

The second argument is the timestamp which is used as a base for the calculation of relative dates; it defaults to the current time. Check out the documentation.

Edit: For short periods of time, max 1 week, adding seconds to a timestamp is perfectly acceptable. There is always (7 * 24 * 3600) seconds in a week; the same cannot be said for a month or year. Furthermore, a unix timestamp is just the number of seconds that have elapsed since the Unix Epoch (January 1 1970 00:00:00 GMT). That is not effected by timezones or daylight-savings. Timezones and daylight-savings are only important when converting a unix timestamp to an actual calendar day and time.

Lawrence Barsanti
"There is always (7 * 24 * 3600) seconds in a week." Not true! http://en.wikipedia.org/wiki/Leap_second and http://en.wikipedia.org/wiki/Daylight_saving_time both change the number of seconds in a week.
ceejayoz
A: 

Probably the safest way to do the compare is right in the SQL

SELECT * FROM my_table WHERE someDateTimeColumn < DATE_ADD(NOW(), INTERVAL 4 hour)

And since you're assembling it in PHP, you can dynamically replace the "4 hour" bit with whatever your code needs to compare.

(Note: putting the entire calculation on the other side of the comparison to the column allows MySQL to do the calculation once per query, rather than once per row, and also use the table's index, if that column has one.)

staticsan
A: 

Assuming that the timestamp returned by the DB is in SQL format, the following should work fine:

$dbTime = strtotime($row[0]);
$nowTime = time();

$future_dbTime = strtotime("+4 hours", $dbTime);

$diff_time_seconds = $nowTime - $dbTime;

if ($diff_time_seconds > 0) {
       echo "The current time is greater than the database time by:\n";
       $not_equal = true;

    }
if ($diff_time_seconds == 0) {
       echo "The current time is equal to the database time!";
    }
if ($diff_time_seconds < 0) {
       echo "The current time is less than the database time by:\n";
       $not_equal = true;
    }

if ($not_equal) {
$diff_time_abs_seconds = abs($diff_time_seconds);
echo date('h:m:s', $diff_time_abs_seconds);
}
Anthony