Добавление времени в PHP

Я извлекаю дату и время из базы данных mysql, и я хотел бы добавить к ней X часов, а затем сравнить ее с текущим временем. До сих пор я получил

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

затем я попробовал $dbTime + strtotime("4 часа"); но 4 часа, кажется, добавляют 4 часа к текущему времени вместо необработанных 4 часов. Как добавить X часов к dbTime?

ПРИМЕЧАНИЕ. Я использую php 5.1.2, поэтому date_add не работает (5.3.0).


person An employee    schedule 21.09.2009    source источник


Ответы (8)


time() и strtotime() приводят к отметкам времени unix в секундах, поэтому вы можете сделать что-то вроде следующего, предоставив свою базу данных и сравнив ее:

$fourHours = 60 * 60 * 4;
$futureTime = time() + $fourHours;
person sparkey0    schedule 21.09.2009

затем я попробовал $dbTime + strtotime("4 часа"); но 4 часа, кажется, добавляют 4 часа к текущему времени вместо необработанных 4 часов. Как добавить X часов к dbTime?

strtotime имеет необязательный второй аргумент. Укажите там временную метку Unix, и вывод будет относиться к этой дате, а не к текущей дате.

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

Вы также можете использовать тот факт, что временные метки Unix основаны на секундах - если вы знаете, что четыре часа в секундах, вы можете просто добавить это к целочисленному значению времени.

person ceejayoz    schedule 21.09.2009
comment
НЕ добавляйте секунды к unixtime! Это начало скользкого пути выполнения всех подобных манипуляций со временем/датой, и это ужасно сложно поддерживать и отлаживать, особенно с учетом часовых поясов и перехода на летнее время. Существуют библиотечные функции, которые корректно обрабатывают все сложные угловые и краевые случаи. - person staticsan; 22.09.2009
comment
Просто добавьте секунды к unixtime! Это то, для чего это было сделано, очевидно. - person Robert L; 22.09.2009
comment
@staticsan, добавление секунд к отметке времени unix вполне приемлемо. Это мера секунд с даты эпохи, и никакие изменения часового пояса или переход на летнее время не повлияют на это. TZ и DST повлияют на удобочитаемую версию, но отметка времени не изменится. - person nickf; 22.09.2009
comment
Это скорее зависит от контекста исходной метки времени и от того, почему она сравнивается с настоящим моментом, чего у нас нет. Если это простой сдвиг на X часов, и этот сдвиг имеет смысл в алгоритме, то простое добавление секунд к отметке времени unix имеет смысл. К сожалению, я видел слишком много кода, который делает это, даже если он не имеет смысла или непонятен, и мне приходилось исправлять возникающие ошибки. - person staticsan; 23.09.2009
comment
если вы хотите узнать, какое текущее время в другом часовом поясе, то нет, вы никогда не должны добавлять/вычитать секунды. если вы хотите узнать, какое время будет через 4 часа, то арифметика временных меток — идеальное решение. - person nickf; 23.09.2009

Здесь у вас довольно много вариантов:

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);
person nickf    schedule 21.09.2009
comment
Если бы я мог понизить часть вашего вопроса, я бы это сделал. # 2 - худшее решение, которое вы могли бы опубликовать. - person staticsan; 22.09.2009
comment
В самом деле? Я бы подумал, что №1 был худшим. Для справки, лично я бы, вероятно, использовал № 3 или № 5, в зависимости от того, насколько я могу контролировать построение SQL-запроса. - person nickf; 22.09.2009
comment
Посмотрите комментарии к ответу ceejayoz, почему я так думаю. - person staticsan; 23.09.2009

strtotime("+4 часа", $dbTime);

Второй аргумент — это метка времени, которая используется в качестве основы для расчета относительных дат; по умолчанию это текущее время. Ознакомьтесь с документацией.

Изменить. Для коротких периодов времени, максимум 1 неделя, добавление секунд к метке времени вполне допустимо. В неделе всегда (7 * 24 * 3600) секунд; то же самое нельзя сказать о месяце или годе. Кроме того, временная метка unix — это просто количество секунд, прошедших с эпохи Unix (1 января 1970 г., 00:00:00 по Гринвичу). На это не влияют часовые пояса или переход на летнее время. Часовые пояса и летнее время важны только при преобразовании временной метки unix в фактический календарный день и время.

person Lawrence Barsanti    schedule 21.09.2009
comment
В неделе всегда (7*24*3600) секунд. Не правда! en.wikipedia.org/wiki/Leap_second и en.wikipedia.org/wiki/Daylight_saving_time изменяют количество секунд в неделе. - person ceejayoz; 22.09.2009

Я склонен использовать функцию time(), и на этой странице руководства показано, как они отображают дату через неделю в будущем: http://us3.php.net/manual/en/function.time.php

person James Black    schedule 21.09.2009

Вот как бы я это сделал:

  1. Извлеките время из базы данных, используя UNIX_TIMESTAMP() функция.

  2. Временная метка UNIX указывается в секундах, поэтому добавьте к ней 4*60*60.

  3. Преобразуйте измененную метку времени UNIX в дату, используя localtime() PHP или strftime().

    query("SELECT UNIX_TIMESTAMP(someDatetimeColumn) ...");
    . . .
    $dbTimeAdjusted = localtime($row[0] + 4*60*60);
    
person Bill Karwin    schedule 21.09.2009

Вероятно, самый безопасный способ сделать сравнение — прямо в SQL.

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

И поскольку вы собираете его на PHP, вы можете динамически заменить бит «4 часа» на все, что нужно вашему коду для сравнения.

(Примечание: размещение всех вычислений с другой стороны сравнения со столбцом позволяет MySQL выполнять вычисления один раз для каждого запроса, а не один раз для каждой строки, а также использовать индекс таблицы, если он есть в этом столбце.)

person staticsan    schedule 21.09.2009

Предполагая, что метка времени, возвращаемая БД, находится в формате SQL, следующее должно работать нормально:

$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);
}
person Anthony    schedule 22.09.2009