due_mode) { DueMode::Fixed => $this->fixed($event, $user), DueMode::Local => $this->local($event, $user), }; } public function fireStart(Event $event, User $user): CarbonImmutable { return self::localMidnight($event->fire_on->format('Y-m-d'), $user->tz); } /** * Старт дня срока. Обычно локальная полночь дня срока. Если момент срока не * позже начала активных часов, первое окно дня уже опоздало бы — тогда старт * за два часа до тихих часов накануне (два последних часовых окна вечера). */ public function todayStart(Due $due, User $user): CarbonImmutable { if ($due->moment->lte($user->activeStart($due->day))) { return $user->activeEnd($due->day->subDay())->subHours(2); } return $due->day; } public static function localMidnight(string $ymd, string $tz): CarbonImmutable { return CarbonImmutable::createFromFormat('Y-m-d', $ymd, $tz)->startOfDay(); } private function local(Event $event, User $user): Due { $day = self::localMidnight($event->due_date->format('Y-m-d'), $user->tz); $moment = $event->due_time === self::WHOLE_DAY ? $day->addDay() : $day->setTimeFromTimeString($event->due_time); return new Due($day, $moment); } private function fixed(Event $event, User $user): Due { $moment = $event->due_instant->setTimezone($user->tz); return new Due($moment->startOfDay(), $moment); } }