PHP strtotime нуждается в корректировке

Я работаю над функцией php для вычисления общего времени между двумя пользовательскими полями ввода времени из плагина WordPress форм, но функция не работает, когда время пересекает 2400 часов.

Вот точная ситуация: я пытаюсь вычислить, как долго пользователь спал, но я получаю отрицательное число, когда время начала - вечером (например, 23:00), а время окончания (просыпаться) - на следующее утро (Например, 07:00) - это потому, что время берется из формы, которая показывает оба раза в один и тот же день, поэтому время начала выглядит больше, чем время окончания при преобразовании с использованием strtotime.

Вот оригинальный код:

add_filter('frm_validate_field_entry', 'calculate_time', 11, 3);
function calculate_time($errors, $field, $value){
if($field->id == 98){ //98 is the field id from the wordpress plugin that will store the total time I'm using
  $start = (strtotime($_POST['item_meta'][88])); //88 is the field id for 'go to sleep time' from the wordpress forms program - the user selects times from 00:00 to 23:00
  $end = (strtotime($_POST['item_meta'][78])); //78 is the field id for 'wake up time' from the wordpress forms program - the user selects times from 00:00 to 23:00
  $totaltime = ($end - $start);
  $hours = intval($totaltime / 3600);   
  $seconds_remain = ($totaltime - ($hours * 3600)); 
  $minutes = intval($seconds_remain / 60);
  $totaltime = $hours . ':' . $minutes; 
  $value = $_POST['item_meta'][98] = $totaltime; //change 25 to the ID of the hidden or admin only field which will hold the calculation
}
return $errors;
}

Вот как я пытался приспособиться, добавив двенадцать часов к времени окончания, если оно было меньше времени начала:

add_filter('frm_validate_field_entry', 'calculate_time', 11, 3);
function calculate_time($errors, $field, $value){
if($field->id == 98){ 
  $start = (strtotime($_POST['item_meta'][88]));
  $end = (strtotime($_POST['item_meta'][78])); 

  if ($end < $start) {
    $end = ($end + 43200)
    $totaltime = ($end - $start);
    $hours = intval($totaltime / 3600);   
    $seconds_remain = ($totaltime - ($hours * 3600)); 
    $minutes = intval($seconds_remain / 60);
    $totaltime = $hours . ':' . $minutes;   
    $value = $_POST['item_meta'][98] = $totaltime; 

} else 

{

  $totaltime = ($end - $start);
  $hours = intval($totaltime / 3600);   
  $seconds_remain = ($totaltime - ($hours * 3600)); 
  $minutes = intval($seconds_remain / 60);
  $totaltime = $hours . ':' . $minutes; 
  $value = $_POST['item_meta'][98] = $totaltime; 
}
}
return $errors;

1 ответ

Решение

Как strtotime состояния

int strtotime ( string $time [, int $now = time() ] )  

Функция ожидает получить строку, содержащую формат даты на английском языке, и попытается проанализировать этот формат в метку времени Unix (количество секунд с 1 января 1970 года 00:00:00 UTC) относительно отметки времени, указанной в настоящее время, или текущее время, если сейчас не указано.

В вашем случае оба времени интерпретируются относительно сегодняшнего дня, то есть сегодня утром в 7 утра и сегодня вечером в 1 1 вечера.

Чтобы это исправить, достаточно либо настроить на целый день, например, 24*60*60 секунд, или дайте завтрашнюю дату в качестве основы для конца. Таким образом, вместо двух больших ветвей, вначале сделайте небольшую корректировку, а затем равномерно рассчитайте разницу

$start = strtotime($_POST['item_meta'][88]);
$end = strtotime($_POST['item_meta'][78]);
if ($end < $start)
    $end += 86400; // shift the end 24 hours into tomorrow

$totaltime = $end - $start;

Не связано, но вам не нужно рассчитывать часы и минуты вручную, используйте DateTime::format вместо

$date = DateTime::createFromFormat('U', $totaltime);
$s = $date->format('H:I');
Другие вопросы по тегам