Files
onboard/app/Services/DateRangeService.php
brusnitsyn eab78a0291 * переписал функции прототипов в сервисы
* оптимизация доставки контента до клиента
* переписал запросы выборок
* убрал из подсчета переведенных
* добавил сохранение метрикам для вывода в дашборд
2026-02-04 17:05:13 +09:00

129 lines
3.5 KiB
PHP

<?php
namespace App\Services;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
class DateRangeService
{
/**
* Получить унифицированный объект диапазона дат
*/
public function getNormalizedDateRange(User $user, ?string $startAt = null, ?string $endAt = null): DateRange
{
[$startDate, $endDate] = $this->getDateRangeForUser($user, $startAt, $endAt);
$startCarbon = Carbon::parse($startDate)->setTimeZone('Asia/Yakutsk');
$endCarbon = Carbon::parse($endDate)->setTimeZone('Asia/Yakutsk');
return new DateRange(
startDate: $startCarbon,
endDate: $endCarbon,
startDateRaw: $startDate,
endDateRaw: $endDate,
isOneDay: $this->isRangeOneDay($startDate, $endDate)
);
}
/**
* Получить диапазон дат из запроса
*/
public function getDateRangeFromRequest(Request $request, User $user): DateRange
{
return $this->getNormalizedDateRange(
$user,
$request->query('startAt', $request->get('startAt')),
$request->query('endAt', $request->get('endAt'))
);
}
public function getDateRangeForUser($user, $startAt = null, $endAt = null): array
{
if ($startAt && $endAt) {
return $this->getCustomDateRange($startAt, $endAt, $user);
}
return $this->getDefaultDateRange($user);
}
public function isRangeOneDay($startAt = null, $endAt = null): bool
{
if (!$startAt || !$endAt) return false;
$startDate = $this->parseDate($startAt);
$endDate = $this->parseDate($endAt);
return $startDate->diffInDays($endDate) === 1.0;
}
private function getCustomDateRange($startAt, $endAt, $user): array
{
$startDate = $this->parseDate($startAt);
$endDate = $this->parseDate($endAt);
if ($startDate->isSameDay($endDate)) {
$startDate = $startDate->subDay()->setTime(6, 0);
$endDate = $endDate->setTime(6, 0);
} else {
$startDate = $startDate->setTime(6, 0);
$endDate = $endDate->setTime(6, 0);
}
return [
$startDate->format('Y-m-d H:i:s'),
$endDate->format('Y-m-d H:i:s')
];
}
private function getDefaultDateRange($user): array
{
$startDate = Carbon::now('Asia/Yakutsk')
->subDay()
->setTime(6, 0);
$endDate = Carbon::now('Asia/Yakutsk')
->setTime(6, 0);
return [
$startDate->format('Y-m-d H:i:s'),
$endDate->format('Y-m-d H:i:s')
];
}
public function parseDate($dateInput): Carbon
{
if (is_numeric($dateInput)) {
return Carbon::createFromTimestampMs($dateInput)
->setTimezone('Asia/Yakutsk');
}
return Carbon::parse($dateInput, 'Asia/Yakutsk');
}
/**
* Конвертировать дату в Carbon объект
*/
public function toCarbon($date): Carbon
{
if ($date instanceof Carbon) {
return $date;
}
if (is_string($date)) {
return Carbon::parse($date, 'Asia/Yakutsk');
}
return Carbon::parse($date);
}
/**
* Получить дату в формате для SQL запроса
*/
public function toSqlFormat($date): string
{
return $this->toCarbon($date)->format('Y-m-d H:i:s');
}
}