Сравнение времени PHP не удается

Я работаю над плагином Wordpress, и у меня проблемы со сравнением времени. Я в основном хочу: если выбранное время раньше текущего, сделайте то, что ... но это не работает.

Проверка не выполняется, если expire опережает время менее чем на пять часов (). Я исправляю это, добавляя gmt offset expire, но он все равно не работает. Любые идеи?

//$_POST['expire'] = '2019-01-31T12:00';

if (validateDate($_POST['expire'])) {
    $expires_epoch = (strtotime($_POST['expire']) - (get_option( 'gmt_offset' ) * HOUR_IN_SECONDS));
    if ($expires_epoch < time()) {
        ...do the thing...
    }
 }

Есть предположения? Это кажется простым, но, похоже, не работает так, как мне хотелось бы.

Что такое date.timezone в вашем php.ini. Распечатайте с помощью функции ini_get и проверьте. В зависимости от часового пояса будет указано текущее время.

Dipti 21.12.2018 06:19

Покажите несколько примеров значений для ввода.

Camilo 03.01.2019 21:33

Входными данными является время ISO8601: 2019-01-31T12:00, которое затем будет преобразовано в метку времени с помощью strtotime.

Sal 03.01.2019 21:37

Есть ли причина не использовать объект DateTime?

Will B. 03.01.2019 22:15

Меня бы устроило, если бы это сработало. Я думаю, что это просто не очень "wordpressy" решение, но на данном этапе я бы попробовал что угодно!

Sal 03.01.2019 22:29

Разве вы не должны просто добавить смещение часового пояса вместо его вычитания? В конце концов, смещение часового пояса может быть положительным или отрицательным, и вычитание будет выполняться автоматически.

asiby 04.01.2019 05:17

@SalCangeloso Не могли бы вы сообщить мне, каково значение «$ _POST ['expire']» и как пользователь может это выбрать?

Praveen Kumar 04.01.2019 07:19

@PraveenKumar, в третьем комментарии он сказал, что значение соответствует времени ISO8601, которое выглядит как 2019-01-31T12: 00. А поскольку это сообщение, его можно отправить с помощью формы и выбрать с помощью виджета календаря. Или его можно было ввести вручную.

asiby 04.01.2019 20:27

Пожалуйста, приведите пример стоимости, которая терпит неудачу, и время. Ваш код выглядит нормально, за исключением того, что часы, на которые вы смотрите, используют другой часовой пояс, чем сервер. В этом случае никаких действий не требуется.

Salman A 05.01.2019 00:23

@SalmanA, когда вы говорите, что "часы" отличаются от сервера, какие часы вы имеете в виду? Я могу сказать вам, что мой местный часовой пояс (ET) отличается от часового пояса сервера (UTC), что является основной проблемой здесь.

Sal 05.01.2019 04:21

@Sal да, это то, что я имел в виду. То, что, по вашему мнению, должно истечь в «12 утра», на самом деле истечет в 5 утра по вашему времени. Решение состоит в том, чтобы устранить двусмысленность ввода: 2019-01-31T12:00 следует указать как 2019-01-31T12:00-05:00.

Salman A 05.01.2019 09:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
11
408
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Думаю, вы неправильно рассчитываете gmt_offset, для WordPress я сделаю такой расчет примерно так,

$gmt = get_option( 'gmt_offset' );
$expires_epoch = strtotime('midnight') + ((24 - $gmt) * HOUR_IN_SECONDS);
if ($expires_epoch < time()){ ... }

Это не будет точным решением, так как я не знаю, что именно такое (strtotime ($ _ POST ['expire'])?

(strtotime($_POST['expire']) - это преобразование моего времени ISO8601 в метку времени, которую я затем хочу сравнить с time (), чтобы увидеть, находится ли expire в прошлом или нет.
Sal 05.01.2019 04:30

В таком случае, пробовали ли вы изменить вторую строку на этом $expires_epoch = (strtotime($_POST['expire']) + ((24 - $gmt) * HOUR_IN_SECONDS);? Он должен работать для wordpress.

Deepak Singh 08.01.2019 23:25

Я пробовал использовать этот код, и у меня он сработал, пожалуйста, проверьте это.

    if (validateDate($_POST['expire'])) {
        $expires_epoch = strtotime($_POST['expire']);
        if ($expires_epoch < time()) {
            echo '...do the thing...';
        }
     }
Ответ принят как подходящий

strtotime ограничен в форматах, которые он может принимать, и не всегда дает желаемые результаты. Чтобы избежать двусмысленности форматов даты, как рекомендует документация PHP, альтернативой является использование DateTime::createFromFormat. Это позволит вам установить желаемый формат прилагаемого $_POST['expire'].

Используя правило формата Y-m-d\TH:i|, принудительно применяет формат ISO-8601, исключая секунды и часовой пояс. | (конвейер) сбрасывает оставшиеся секунды на :00, иначе PHP будет использовать текущие секунды.

Если вы хотите, чтобы ваш код запускал ПОСЛЕ по истечении срока годности, вам просто нужно сравнить expire_date < current_date.

Пример: https://3v4l.org/EelYY

//current date is 2019-01-04 08:33:30
//$_POST['expire'] = '2019-01-04T08:32';

if ($expire_date = \DateTime::createFromFormat('Y-m-d\TH:i|', $_POST['expire'])) {
    $current_date = new \DateTime();
    if ($expire_date < $current_date) {
        /* example purposes only */
        $diff = $expire_date->diff($current_date);
        echo 'Expired ' . $diff->format('%y years %m months %d days %h hours %i minutes %s seconds') . ' ago';
        //do the thing
    }
} else {
    die('Invalid Date Format Provided');
}

Результат

Expired 0 years 0 months 0 days 0 hours 1 minutes 30 seconds ago

Для разъяснения того, как и зачем использовать смещение часового пояса из Wordpress.

PHP по умолчанию будет использовать date.timezone, указанный в вашем php.ini, при работе с объектами date(), time(), strtotime() и DateTime. Это важно только для Wordpress и большинства других приложений, когда даты отображение, сгенерированные вашим приложением для средства просмотра, или при приеме строки даты от пользователя, которая должна быть сохранена и отображена для других пользователей. Например, отображение времени создания публикации или ожидаемого события. В противном случае смещение часового пояса пользователя обычно можно игнорировать, поскольку PHP будет применять собственное смещение часового пояса к анализируемым датам.

Например, по умолчанию PHP date.timezone - это UTC. Я создаю мероприятие, которое хочу провести на 2019-01-01 09:00 в свое время (EST). Но мероприятие начнется для кого-то из Калифорнии (PST) за 3 часа до 2019-01-01 06:00.

Чтобы отобразить событие для других пользователей, дату необходимо преобразовать из смещения часового пояса пользователя EST в UTC и сохранить в базе данных. Затем конвертируется из UTC для отображения в другом часовом поясе.

Пример: https://3v4l.org/vA97A

$defaultTZ = new \DateTimeZone(date_default_timezone_get());
$event_start = '2019-01-01 09:00';
//event starts at 2019-01-01 09:00 EST
$est_date = new \DateTimeImmutable($event_start, new \DateTimeZone('America/New_York'));
//convert to native date to save in database
$utc_date = $est_date->setTimeZone($defaultTZ);
$db_date = $utc_date->format(DATE_ISO8601);

//event starts at 2019-01-01 14:00 UTC
$db_event_start = '2019-01-01T14:00:00+0000';
$event_date = new \DateTimeImmutable($db_event_start, $defaultTZ);

//display the start times to users
$pst_date = $event_date->setTimeZone(new \DateTimeZone('America/Los_Angeles'));
$est_date = $event_date->setTimeZone(new \DateTimeZone('America/New_York'));

echo 'Event Starts at:';
echo $event_date->format('Y-m-d H:i T');
echo $pst_date->format('Y-m-d H:i T');
echo $est_date->format('Y-m-d H:i T');

//display event status
echo 'Event ' . ($event_date <= new \DateTime('now', $defaultTZ) ? 'Has' : 'Not') . ' Started';

Результат

Event Starts at:
2019-01-01 14:00 GMT+0000
2019-01-01 06:00 PST
2019-01-01 09:00 EST
Event Has Started

For WordPress you would generally replace date_default_timezone_get() with get_option('timezone_string') to use the application timezone offset instead of PHP's default timezone offset.

Другие вопросы по теме