Как я могу создать относительный PHP DateTime для следующего экземпляра определенного времени? - PullRequest
0 голосов
/ 27 января 2020

Так что, похоже, класс PHP DateTime позволяет использовать простые строки относительного языка, например next Monday 12:00, для создания объектов, связанных с относительными датами.

Проблема

Вариант использования, которого я хотел бы достичь, - это опустить день («понедельник») в приведенной выше строке и создать DateTime объект для следующего экземпляра 06:00.

Это представляет проблему, потому что код может выполняться на 07:00, и в этом случае строка 06:00 вернет дату, которая была в прошлом, тогда как если мы запустим код на 05:00 ( или в любое время до 06:00), мы получим правильный результат.

Примечание: В качестве дополнения я не хочу делать кучу сложных арифметических действий c и хочу использовать класс DateTime в полной мере, чтобы оградить себя от каких-либо хитрых проблем TimeZone или високосного года.

Мой вопрос

Как использовать класс PHP DateTime для получить объект DateTime для следующего экземпляра определенного времени (w не снабжать день тоже)?

Ответы [ 2 ]

1 голос
/ 28 января 2020

Я создал расширение PHP для API DateTime под названием dt. Вы можете найти это здесь . Использовать его для этой задачи очень просто. Некоторые примеры:

$dt = dt::create("today 06:00");
if($dt->isPast()) {
  $dt->modify("+ 1Day");
}
echo $dt; 

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

$time = "06:00";
$dt = dt::create("today $time","Africa/Johannesburg"); 
//:

Класс работает со специальными цепочками, которые могут содержать условия. Это позволяет вам создать выражение, которое выполняет работу только с помощью метода create.

$dt = dt::create("today 6:00|{{?YmdHis<NOW}}+1 Day");

Класс также работает с выражениями cron.

$cron = "0 6 * * 1-5";//every Mo-Fr at 6:00
$dt = dt::create('now')->nextCron($cron);

Всегда доставляет в следующий раз 6: 00 с понедельника по пятницу. В выходные в следующий раз понедельник 6:00.

0 голосов
/ 27 января 2020

Решение

Вот как я решил эту проблему ...

/*
 * Simple function that returns a DateTime object representing the next instance of the time
 * supplied by the $timeString parameter.  
 *
 * $timeString: A string representing the time you wish to process, in 24h notation (i.e. 
 * '06:00' for 6:00am).
 */
function getNextTimeInstance($timeString){

  // First, grab an instance of the current moment as a DateTime object ('now' is optional).
  $rightNow = new DateTime('now');

  // Basic initializations for the object we want to use.
  $processedTime = new DateTime();

  // Change the Timezone if you need to do so.
  $processedTime->setTimezone(new DateTimeZone('Africa/Johannesburg'));

  // Set the time for our working DateTime to the time we want (i.e. '06:00').
  $processedTime->modify($timeString);

  // If the next instance of this time we're trying to process is in the past 
  // (meaning it is "less than" the current moment).
  if($rightNow > $processedTime){

    // Simply add one day to our working DateTime object. 
    $processedTime->modify('+1 day');
  }

  // Return the DateTime objects that represents the next instance of that time.
  return $processedTime;
}

Для достижения этого результата я опирался на следующую документацию:


Я надеюсь, что это поможет кому-то еще застрявшему в той же ситуации, что и я, и если у кого-то еще есть более элегантное решение, пожалуйста, не стесняйтесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...