Я работаю над плагином 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...
}
}
Есть предположения? Это кажется простым, но, похоже, не работает так, как мне хотелось бы.
Покажите несколько примеров значений для ввода.
Входными данными является время ISO8601: 2019-01-31T12:00, которое затем будет преобразовано в метку времени с помощью strtotime.
Есть ли причина не использовать объект DateTime?
Меня бы устроило, если бы это сработало. Я думаю, что это просто не очень "wordpressy" решение, но на данном этапе я бы попробовал что угодно!
Разве вы не должны просто добавить смещение часового пояса вместо его вычитания? В конце концов, смещение часового пояса может быть положительным или отрицательным, и вычитание будет выполняться автоматически.
@SalCangeloso Не могли бы вы сообщить мне, каково значение «$ _POST ['expire']» и как пользователь может это выбрать?
@PraveenKumar, в третьем комментарии он сказал, что значение соответствует времени ISO8601, которое выглядит как 2019-01-31T12: 00. А поскольку это сообщение, его можно отправить с помощью формы и выбрать с помощью виджета календаря. Или его можно было ввести вручную.
Пожалуйста, приведите пример стоимости, которая терпит неудачу, и время. Ваш код выглядит нормально, за исключением того, что часы, на которые вы смотрите, используют другой часовой пояс, чем сервер. В этом случае никаких действий не требуется.
@SalmanA, когда вы говорите, что "часы" отличаются от сервера, какие часы вы имеете в виду? Я могу сказать вам, что мой местный часовой пояс (ET) отличается от часового пояса сервера (UTC), что является основной проблемой здесь.
@Sal да, это то, что я имел в виду. То, что, по вашему мнению, должно истечь в «12 утра», на самом деле истечет в 5 утра по вашему времени. Решение состоит в том, чтобы устранить двусмысленность ввода: 2019-01-31T12:00 следует указать как 2019-01-31T12:00-05:00.






Думаю, вы неправильно рассчитываете 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 в прошлом или нет.
В таком случае, пробовали ли вы изменить вторую строку на этом $expires_epoch = (strtotime($_POST['expire']) + ((24 - $gmt) * HOUR_IN_SECONDS);? Он должен работать для wordpress.
Я пробовал использовать этот код, и у меня он сработал, пожалуйста, проверьте это.
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.
//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 для отображения в другом часовом поясе.
$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()withget_option('timezone_string')to use the application timezone offset instead of PHP's default timezone offset.
Что такое date.timezone в вашем php.ini. Распечатайте с помощью функции ini_get и проверьте. В зависимости от часового пояса будет указано текущее время.