Минутный интервал между двумя разами за полночь в php - PullRequest
0 голосов
/ 03 апреля 2020

Пользователям разрешено выбирать время для доставки до времени закрытия магазина, которое может быть 1 час утра.

Список должен отображаться все время до 1 часа ночи, даже если это после полуночи.

пример 1: пользователь приходит на 18:00 он видит 18:00, 18:30, 19:00 and so on up until 00:30, 01:00

пример 2: пользователь приходит на 00:10 должен видеть

00:30, 01:00 not
01:00, 01:30, 02:00, 02:30 etc because after midnight has become a has become a new day/date.

Я получаю 30 минут времени интервалы между двумя временами - это нормально, если оба раза находятся в один и тот же день, например 17:00 and 23:00 Если время окончания больше полуночи, я не могу получить интервалы, поэтому 17:00 to 01:00 не дает никаких интервалов.

Я понимаю, что 01:00 - это другой день, но я не совсем уверен, как это исправить, используя Dynami c дата. Я продолжаю думать, что current day +1 будет хорошо, если только это не будет после осознания, тогда это будет дополнительный день, если это имеет смысл.

Вот мой код:

$timestamp = time() + 60*60;
$earliest = date("h:i ",$timestamp);
$period = new DatePeriod(
new DateTime($earliest),
new DateInterval('PT30M'),
new DateTime('01:00')
);
foreach ($period as $date) {
echo '<option value="">'.$date->format("H:i").'</option>';
}

Поскольку работает 24:00 в 00:00 я пытался 25:00, но это не сработало. Любая помощь приветствуется!

ОБНОВЛЕНИЕ: после приведенного ниже ответа применительно к динамической c дате, если я использую дату, такую ​​как:

$start = date('Y-m-d H:i');
$startdate = date('Y-m-d');
$end = date('Y-m-d', strtotime($startdate . ' +1 day'))." 01:00"; 
$period = new DatePeriod(
DateTime::createFromFormat('Y-m-d H:i','2020-04-03 17:00'),
new DateInterval('PT30M'),
DateTime::createFromFormat('Y-m-d H:i','2020-04-04 01:00')
      );

После полуночи добавляется еще один день, который проблематичен c.

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Вы можете потерять весь расчет отметки времени и обработать все это с помощью DateTime:

// here we get the next round delivery time
$nextAvailableHalfHour = getNextHalfHourMark();
$todayMidnight = new DateTime('today'); // this creates today with time 00:00:00
$todayOneOclock = new DateTime('today 01:00'); // this creates today with time 01:00:00
// this condition says if we're now between midnight and 1 o'clock, use today
// otherwise use tomorrow
$endDate = $nextAvailableHalfHour >= $todayMidnight && $nextAvailableHalfHour <= $todayOneOclock
    ? $todayOneOclock
    : new DateTime('tomorrow 01:00'); // create specific time tomorrow
$period = new DatePeriod(
    $nextAvailableHalfHour,
    new DateInterval('PT30M'),
    $endDate
);

/**
 * Gets the next available time with round half hour (:00 or :30).
 */
function getNextHalfHourMark(): DateTime
{
    $now = new DateTime(); // create current date and time
    $currentMinutes = (int) $now->format('i');
    // if we are between :00 and :30
    if ($currentMinutes > 0 && $currentMinutes < 30) {
        // set to :30 minutes of current hour
        $now->setTime($now->format('H'), 30);
    // else if we are between :30 and :00
    } elseif ($currentMinutes > 30 && $currentMinutes <= 59) {
        // set to :00 minutes of next hour
        $now->setTime($now->format('H') + 1, 00);
    }

    return $now;
}

Строки tomorrow и today активируются с помощью относительных форматов .

1 голос
/ 03 апреля 2020

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

<?php

$period = new DatePeriod(
                        DateTime::createFromFormat('Y-m-d H:i','2020-04-03 17:00'),
                        new DateInterval('PT30M'),
                        DateTime::createFromFormat('Y-m-d H:i','2020-04-04 01:00')
          );



foreach ($period as $date) {
    echo $date->format("H:i"),PHP_EOL;
}

Демо: https://3v4l.org/5sj9Z

Обновление:

Поскольку у вас есть только время, а не даты, вы создаете объекты DateTime, сравниваете их, добавляете время окончания 1 дня, если оно меньше, и затем l oop через интервалы, используя DatePeriod

<?php

$times = [
        ['18:00','01:00'],
        ['17:00','23:00'],
        ['00:10','01:00']
    ];

foreach($times as $time){
    $start_time = DateTime::createFromFormat('H:i',$time[0]);
    $end_time = DateTime::createFromFormat('H:i',$time[1]);
    if($end_time < $start_time){
        $end_time->add(new DateInterval('P1D'));
    }
    $period = new DatePeriod(
                        $start_time,
                        new DateInterval('PT30M'),
                        $end_time
              );


    echo $start_time->format('Y-m-d H:i:s'),' ',$end_time->format('Y-m-d H:i:s'),PHP_EOL;
    foreach ($period as $date) {
        echo $date->format("H:i"),PHP_EOL;
    }
    echo PHP_EOL;
}

Демо: https://3v4l.org/Ldpst

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