112 lines
2.9 KiB
PHP
112 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use Carbon\Carbon;
|
||
use Illuminate\Support\Collection;
|
||
|
||
readonly class DateRange
|
||
{
|
||
public function __construct(
|
||
public Carbon $startDate,
|
||
public Carbon $endDate,
|
||
public string $startDateRaw,
|
||
public string $endDateRaw,
|
||
public bool $isOneDay,
|
||
// То, что реально выбрал пользователь в календаре — без служебного сдвига
|
||
// конца периода на +1 сутки (см. DateRangeService::getCustomDateRange).
|
||
// Используется только для отображения в UI, а не для запросов в БД.
|
||
public ?Carbon $displayEndDate = null,
|
||
) {}
|
||
|
||
/**
|
||
* Конец периода для отображения в календаре (без служебного сдвига на +1 сутки)
|
||
*/
|
||
public function displayEnd(): Carbon
|
||
{
|
||
return $this->displayEndDate ?? $this->endDate;
|
||
}
|
||
|
||
/**
|
||
* Получить начало диапазона в Carbon
|
||
*/
|
||
public function start(): Carbon
|
||
{
|
||
return $this->startDate;
|
||
}
|
||
|
||
/**
|
||
* Получить конец диапазона в Carbon
|
||
*/
|
||
public function end(): Carbon
|
||
{
|
||
return $this->endDate;
|
||
}
|
||
|
||
/**
|
||
* Получить начало диапазона в SQL формате
|
||
*/
|
||
public function startSql(): string
|
||
{
|
||
return $this->startDate->format('Y-m-d H:i:s');
|
||
}
|
||
|
||
/**
|
||
* Получить конец диапазона в SQL формате
|
||
*/
|
||
public function endSql(): string
|
||
{
|
||
return $this->endDate->format('Y-m-d H:i:s');
|
||
}
|
||
|
||
/**
|
||
* Получить начало диапазона как timestamp
|
||
*/
|
||
public function startTimestamp(): int
|
||
{
|
||
return $this->startDate->getTimestampMs();
|
||
}
|
||
|
||
/**
|
||
* Получить конец диапазона как timestamp
|
||
*/
|
||
public function endTimestamp(): int
|
||
{
|
||
return $this->endDate->getTimestampMs();
|
||
}
|
||
|
||
public function startFirstOfMonth()
|
||
{
|
||
return $this->startDate->copy()->firstOfMonth()->setHour(9)->format('Y-m-d H:i:s');
|
||
}
|
||
|
||
public function endFirstOfMonth()
|
||
{
|
||
return $this->endDate->copy()->firstOfMonth()->setHour(9)->format('Y-m-d H:i:s');
|
||
}
|
||
|
||
/**
|
||
* Проверить, является ли дата сегодняшней
|
||
*/
|
||
public function isEndDateToday(): bool
|
||
{
|
||
return $this->endDate->isToday();
|
||
}
|
||
|
||
/**
|
||
* Получить диапазон дней
|
||
*/
|
||
public function getDaysRange(): Collection
|
||
{
|
||
$days = collect();
|
||
$current = $this->startDate->copy();
|
||
|
||
while ($current->lte($this->endDate)) {
|
||
$days->push($current->copy());
|
||
$current->addDay();
|
||
}
|
||
|
||
return $days;
|
||
}
|
||
}
|