Найти следующее вхождение заданного времени после заданной отметки времени - PullRequest
0 голосов
/ 26 февраля 2019

Учитывая произвольную метку времени (например, 2019-02-26 10:30:00), я хотел бы найти следующее вхождение произвольного времени.

Например, следующее вхождение 12:00:00 будет 2019-02-26 12:00:00, но следующеепоявление 09:00:00 будет на следующий день в 2019-02-27 09:00:00.Результаты могут быть Carbon или Datetime объектами.Время теста будет просто строкой, как показано.

Есть ли способ рассчитать это в собственном PHP или PHP Carbon без условной упаковки в промежутки времени.Очевидным способом было бы проверить, прошло ли тестируемое время время проверки для today, и если это так, принять результат за время проверки плюс 24 часа (на следующий день).Мне кажется, что слишком много прерываний и объединений дат и времени, так есть ли способ рассчитать его, считая время простой линейной линией?

Все время будет в одном часовом поясе с DST,Примечание: произвольные даты и время проверки не будут зависеть от изменений DST, то есть от 01:00 до 02:00, так что, надеюсь, они не будут проблемой для принятия во внимание.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Вот то, что я сейчас использую через Carbon, что дает мне правильные результаты:

        $dateTime = Carbon::parse('2019-03-30 17:34:50', 'Europe/London');

        $testTime = '16:00:00';

        list ($hour, $minute, $second) = explode(':', $testTime);

        $nextTimeOccurrence = $dateTime
            ->copy() // Carbon 1 only
            ->hour($hour)->minute($minute)->second($second);

        if ($dateTime->gt($nextTimeOccurrence)) {
            $nextTimeOccurrence = $nextTimeOccurrence->addDay();
        }

        // $nextTimeOccurrence is the next occurrence of $testTime after $dateTime

Разделение времени кажется неуклюжим, но может быть лучшим способом?Подход заключается в следующем:

  • Создайте метку времени с временем теста в тот же день, что и метка времени, которую я проверяю.Это будет метка времени, которую я ищу.
  • Если метка времени, которую я проверяю, идет после метки времени, созданной на предыдущем шаге, то добавьте к ней день.

IЯ проверил это вокруг летнего времени, и, к счастью, Carbon / Datetime сохраняет то же время при добавлении дня в течение периода летнего времени, где день будет 25 или 23 часа, в зависимости от того, как он идет.

Я все еще думаю, что есть более "линейное время" способ сделать это, но это кажется простым и надежным.Спасибо @ michael-stokoe здесь, в офисе, за мое руководство по этому вопросу.

0 голосов
/ 26 февраля 2019

Краткий ответ - нет для PHP (частичный ответ, я не специалист по Carbon, но из краткого обзора это тоже нет, но вы можете создать макрос из следующего кода).

Однако, с троичнымусловие, что однострочник достаточно ИМХО (замените второй DateTime($str) на DateTime(), если вы хотите сравнить с текущей датой и временем, и измените >= на >, если вы хотите на следующий день, когда сравниваемое времяточно так же):

$str = '2019-02-26 10:30:00';

$date1 = ( ($a = (new DateTime($str))->setTime(12,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');

$date2 = ( ($a = (new DateTime($str))->setTime(9,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');

echo $date1->format('Y-m-d H:i:s'); //2019-02-26 12:00:00
echo $date2->format('Y-m-d H:i:s'); //2019-02-27 09:00:00

быстрое примечание: вы дали нам не метку времени, а отформатированную дату.

...