georgich
@georgich

Как проверить, входит ли текущее время в заданный диапазон?

Приветствую.
Задача: есть временной диапазон в строковом формате (например 12:00-02:00), есть название текущего дня недели (например Friday) и текущее время (например 14:03), которое меняется при перезагрузке страницы. Как грамотно и без велосипедов проверить текущее время на вхождение в заданный интервал? При этом учесть, что 02:00 это уже время завтрашнего дня. Формат времени - 24-х часовой.
Спасибо.
  • Вопрос задан
  • 9192 просмотра
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Алгоритм тут достаточно простой - вам нужно диапазон преобразовать в две даты - начало и конец диапазона.
А потом просто сравнить текущее время с ними.
Разбивка диапазона - операция достаточно простая, попробуйте справиться самостоятельно и если что-то не получится, приходите снова с конкретными вопросами.

Накидал примерное решение из интереса. Рекомендую всё-таки решить задачу самостоятельно и потом сравнить.
Spoiler alert!
$periodString = '12:00-02:00';
$weekDay = 'Friday';

$period = [
	'start' => new DateTime(),
	'end' => new DateTime(),
];

$day = (int)date('d', strtotime('this '.$weekDay));
$month = (int)date('m', strtotime('this '.$weekDay));
$year = (int)date('Y', strtotime('this '.$weekDay));

foreach (array_combine(['start', 'end'], explode('-', $periodString)) as $type => $part)
{
	list($hour, $minute) = explode(':', $part);
	$hour = (int)$hour;
	$minute = (int)$minute;

	$date = $period[$type];

	$date->setDate($year, $month, $day);
	$date->setTime($hour, $minute);
}

if ($period['start'] > $period['end'])
{
	$period['end']->add(new DateInterval('P1D'));
}

$now = new DateTime();

$isInInterval = $now >= $period['start'] && $now <= $period['end'];

var_dump($isInInterval);



А можно пойти немного дальше:
Бугага :)
class Interval
{
	private $data;
	private $timezone;
	private $start;
	private $end;

	public function __construct($serialized, $timezoneName = 'UTC')
	{
		$this->parse($serialized);
		$this->timezone = new DateTimeZone($timezoneName);
		$this->makeStart();
		$this->makeEnd();
	}

	public function contains(DateTimeInterface $date)
	{
		return $date >= $this->start && $date <= $this->end;
	}

	public function isNow()
	{
		$now = new DateTimeImmutable('now', $this->timezone);
		return $this->contains($now);
	}

	private function parse($serialized)
	{
		$parts = explode('-', $serialized);

		$this->data = [
			'start' => $this->parsePart($parts[0]),
			'end' => $this->parsePart($parts[1]),
		];
	}

	private function makeStart()
	{
		$this->start = $this->makeDate($this->data['start']['hour'], $this->data['start']['minute']);
	}

	private function makeEnd()
	{
		$this->end = $this->makeDate($this->data['end']['hour'], $this->data['end']['minute']);
		$this->ensureEndIsAfterStart();
	}

	private function parsePart($part)
	{
		list($hour, $minute) = explode(':', $part);

		return [
			'hour' => $hour,
			'minute' => $minute,
		];
	}

	private function makeDate($hour, $minute)
	{
		list($day, $month, $year) = explode('.', date('d.m.Y'));

		$date = new DateTime('now', $this->timezone);

		$date->setDate($year, $month, $day);
		$date->setTime($hour, $minute);

		return $date;
	}

	private function ensureEndIsAfterStart()
	{
		if ($this->start > $this->end)
		{
			$this->end->add(new DateInterval('P1D'));
		}
	}
}



// Примеры использования:
$interval = new Interval('11:59-02:00', 'Europe/Moscow');
var_dump($interval->isNow());

$date = new DateTime('now', new DateTimeZone('Europe/Moscow'));
$date->add(new DateInterval('PT8H'));
var_dump($interval->contains($date));

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
iResource
@iResource
Разработчик IR XML2Ozon
Ещё один вариант:

// https://iresurs.com
$opening_hours = '11:00 - 01:00';
$opening_start = trim(explode('-', $opening_hours)[0]);
$opening_start_hours = explode(':', $opening_start)[0];
$opening_start_minutes = explode(':', $opening_start)[1];
$opening_start_today = $opening_start_hours * 60 + $opening_start_minutes;
// echo $opening_start_today.'<br>';
$opening_end = trim(explode('-', $opening_hours)[1]);
$opening_end_hours = explode(':', $opening_end)[0];
$opening_end_minutes = explode(':', $opening_end)[1];
$opening_end_today = $opening_end_hours * 60 + $opening_end_minutes;
if ($opening_end_today <= $opening_start_today) $opening_end_today = 24 * 60 + $opening_end_today;
// echo $opening_end_today.'<br>';
$config = JFactory::getConfig(); // это для CMS Joomla
$zone = $config->get('offset'); // часовой пояс (зона)
// echo $zone.'<br>';
$now = new DateTime('now', new DateTimeZone($zone));
$now_hours = $now->format('H');
$now_minutes = $now->format('i');
$now_today = $now_hours * 60 + $now_minutes;
// echo $now_today.'<br>';
if ($now_today > $opening_start_today && $now_today < $opening_end_today) {
    echo $output;
} else {
    echo '<div class="cart-view"><h1>Время приёма заказов: '.$opening_hours.'</h1><p>Пожалуйста, зайдите позже.</p></div>';
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы