Вход Регистрация
Файл: vendor/laravel/framework/src/Illuminate/Console/Scheduling/CronExpressionTimezoneConverter.php
Строк: 225
<?php

namespace IlluminateConsoleScheduling;

use 
DateTimeZone;
use 
IlluminateSupportCarbon;
use 
IlluminateSupportCollection;

class 
CronExpressionTimezoneConverter
{
    
/**
     * Convert an event cron expression to the display timezone.
     *
     * Returns one or more expressions when values straddle a day boundary.
     *
     * @param  IlluminateConsoleSchedulingEvent  $event
     * @param  DateTimeZone  $timezone
     * @return array<string>
     */
    
public static function forEvent(Event $event, DateTimeZone $timezone)
    {
        
$eventTimezone = static::resolveEventTimezone($event, $timezone);

        [
$totalOffsetMinutes, $hourOffset, $minuteOffset] = static::offsetComponents(
            
$eventTimezone, $timezone
        
);

        if (
$totalOffsetMinutes === 0) {
            return [
$event->expression];
        }

        
$segments = preg_split("/s+/", $event->expression);
        
$minuteGroups = static::shiftAndGroup($segments[0], $minuteOffset, 60);

        
$expressions = [];

        foreach (
$minuteGroups as $minuteCarry => $minuteValues) {
            
$hourGroups = static::shiftAndGroup($segments[1], $hourOffset + $minuteCarry, 24);

            foreach (
$hourGroups as $hourCarry => $hourValues) {
                
$parts = $segments;
                
$parts[0] = $minuteValues;
                
$parts[1] = $hourValues;

                foreach (static::
expressionsForHourCarry($segments, $parts, $hourCarry) as $expression) {
                    
$expressions[] = $expression;
                }
            }
        }

        return 
$expressions;
    }

    
/**
     * Resolve the timezone used by the given event.
     *
     * @param  IlluminateConsoleSchedulingEvent  $event
     * @param  DateTimeZone  $defaultTimezone
     * @return DateTimeZone
     */
    
protected static function resolveEventTimezone(Event $event, DateTimeZone $defaultTimezone)
    {
        return 
$event->timezone instanceof DateTimeZone
            
? $event->timezone
            
: new DateTimeZone($event->timezone ?? $defaultTimezone->getName());
    }

    
/**
     * Get offset components between the event and display timezones.
     *
     * @return array{int, int, int}
     */
    
protected static function offsetComponents(DateTimeZone $eventTimezone, DateTimeZone $displayTimezone)
    {
        
$now = Carbon::now();

        
$totalOffsetMinutes = intdiv(
            
$displayTimezone->getOffset($now) - $eventTimezone->getOffset($now),
            
60
        
);

        return [
$totalOffsetMinutes, intdiv($totalOffsetMinutes, 60), $totalOffsetMinutes % 60];
    }

    
/**
     * Build expressions for the given hour carry direction.
     *
     * @param  array<int, string>  $segments
     * @param  array<int, string>  $parts
     * @return array<int, string>
     */
    
protected static function expressionsForHourCarry(array $segments, array $parts, int $hourCarry)
    {
        if (
$hourCarry === 0) {
            return [
implode(' ', $parts)];
        }

        
$parts[4] = static::shiftField($segments[4], $hourCarry, 7);

        
$dayGroups = static::shiftAndGroup($segments[2], $hourCarry, 31, min: 1);

        
$expressions = [];

        foreach (
$dayGroups as $dayCarry => $dayValues) {
            
$dayParts = $parts;
            
$dayParts[2] = $dayValues;

            if (
$dayCarry !== 0) {
                
$dayParts[3] = static::shiftField($segments[3], $dayCarry, 12, min: 1);
            }

            
$expressions[] = implode(' ', $dayParts);
        }

        return 
$expressions;
    }

    
/**
     * Shift values in a cron field and group them by carry direction.
     *
     * @param  string  $field
     * @param  int  $offset
     * @param  int  $mod
     * @return array<int, string>
     */
    
protected static function shiftAndGroup($field, $offset, $mod, $min = 0)
    {
        if (
$offset === 0 || ! preg_match('/^[d,]+$/', $field)) {
            return [
0 => $field];
        }

        
$groups = [];

        foreach (
explode(',', $field) as $value) {
            
$new = (int) $value + $offset;
            
$carry = 0;

            if (
$new >= $mod + $min) {
                
$carry = 1;
                
$new -= $mod;
            } elseif (
$new < $min) {
                
$carry = -1;
                
$new += $mod;
            }

            
$groups[$carry][] = $new;
        }

        return (new 
Collection($groups))->map(function ($values) {
            
sort($values);

            return 
implode(',', $values);
        })->
all();
    }

    
/**
     * Shift a cron field by the given offset.
     *
     * @param  string  $field
     * @param  int  $offset
     * @param  int  $mod
     * @param  int  $min
     * @return string
     */
    
protected static function shiftField($field, $offset, $mod, $min = 0)
    {
        if (
$offset === 0 || ! preg_match('/^[d,]+$/', $field)) {
            return 
$field;
        }

        
$shifted = (new Collection(explode(',', $field)))
            ->
map(fn ($v) => (((int) $v + $offset - $min) % $mod + $mod) % $mod + $min)
            ->
sort();

        return 
$shifted->implode(',');
    }
}
Онлайн: 2
Реклама