diff --git a/app/Filament/Server/Resources/Schedules/Pages/CreateSchedule.php b/app/Filament/Server/Resources/Schedules/Pages/CreateSchedule.php
index 10f00e406..53e50726c 100644
--- a/app/Filament/Server/Resources/Schedules/Pages/CreateSchedule.php
+++ b/app/Filament/Server/Resources/Schedules/Pages/CreateSchedule.php
@@ -39,13 +39,17 @@ class CreateSchedule extends CreateRecord
$data['server_id'] = $server->id;
}
+ $timezone = $data['timezone'] ?? user()->timezone ?? 'UTC';
+ unset($data['timezone']);
+
if (!isset($data['next_run_at'])) {
$data['next_run_at'] = ScheduleResource::getNextRun(
$data['cron_minute'],
$data['cron_hour'],
$data['cron_day_of_month'],
$data['cron_month'],
- $data['cron_day_of_week']
+ $data['cron_day_of_week'],
+ $timezone
);
}
diff --git a/app/Filament/Server/Resources/Schedules/Pages/EditSchedule.php b/app/Filament/Server/Resources/Schedules/Pages/EditSchedule.php
index eff631ff9..cb8dab2d1 100644
--- a/app/Filament/Server/Resources/Schedules/Pages/EditSchedule.php
+++ b/app/Filament/Server/Resources/Schedules/Pages/EditSchedule.php
@@ -37,12 +37,16 @@ class EditSchedule extends EditRecord
protected function mutateFormDataBeforeSave(array $data): array
{
+ $timezone = $data['timezone'] ?? user()->timezone ?? 'UTC';
+ unset($data['timezone']);
+
$data['next_run_at'] = ScheduleResource::getNextRun(
$data['cron_minute'],
$data['cron_hour'],
$data['cron_day_of_month'],
$data['cron_month'],
- $data['cron_day_of_week']
+ $data['cron_day_of_week'],
+ $timezone
);
return $data;
diff --git a/app/Filament/Server/Resources/Schedules/ScheduleResource.php b/app/Filament/Server/Resources/Schedules/ScheduleResource.php
index a9ed0e4cf..89207a14d 100644
--- a/app/Filament/Server/Resources/Schedules/ScheduleResource.php
+++ b/app/Filament/Server/Resources/Schedules/ScheduleResource.php
@@ -100,13 +100,15 @@ class ScheduleResource extends Resource
Section::make('Cron')
->label(trans('server/schedule.cron'))
->description(function (Get $get) {
+ $timezone = $get('timezone') ?? user()->timezone ?? 'UTC';
+
try {
- $nextRun = Utilities::getScheduleNextRunDate($get('cron_minute'), $get('cron_hour'), $get('cron_day_of_month'), $get('cron_month'), $get('cron_day_of_week'))->timezone(user()->timezone ?? 'UTC');
+ $nextRun = Utilities::getScheduleNextRunDate($get('cron_minute'), $get('cron_hour'), $get('cron_day_of_month'), $get('cron_month'), $get('cron_day_of_week'), $timezone)->timezone($timezone);
} catch (Exception) {
$nextRun = trans('server/schedule.invalid');
}
- return new HtmlString(trans('server/schedule.cron_body') . '
' . trans('server/schedule.cron_timezone', ['timezone' => user()->timezone ?? 'UTC', 'next_run' => $nextRun]));
+ return new HtmlString(trans('server/schedule.cron_body', ['timezone' => $timezone]) . '
' . trans('server/schedule.cron_timezone', ['timezone' => $timezone, 'next_run' => $nextRun]));
})
->schema([
Actions::make([
@@ -295,6 +297,13 @@ class ScheduleResource extends Resource
'default' => 4,
'lg' => 5,
]),
+ Select::make('timezone')
+ ->label(trans('server/schedule.timezone'))
+ ->options(fn () => array_combine(timezone_identifiers_list(), timezone_identifiers_list()))
+ ->default(user()->timezone ?? 'UTC')
+ ->searchable()
+ ->live()
+ ->hiddenOn('view'),
])
->columnSpanFull(),
]);
@@ -379,10 +388,10 @@ class ScheduleResource extends Resource
];
}
- public static function getNextRun(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek): Carbon
+ public static function getNextRun(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek, string $timezone = 'UTC'): Carbon
{
try {
- return Utilities::getScheduleNextRunDate($minute, $hour, $dayOfMonth, $month, $dayOfWeek);
+ return Utilities::getScheduleNextRunDate($minute, $hour, $dayOfMonth, $month, $dayOfWeek, $timezone);
} catch (Exception) {
Notification::make()
->title(trans('server/schedule.notification_invalid_cron'))
diff --git a/app/Helpers/Utilities.php b/app/Helpers/Utilities.php
index cef0ccff2..df745e7b5 100644
--- a/app/Helpers/Utilities.php
+++ b/app/Helpers/Utilities.php
@@ -38,11 +38,11 @@ class Utilities
*
* @throws Exception
*/
- public static function getScheduleNextRunDate(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek): Carbon
+ public static function getScheduleNextRunDate(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek, string $timezone = 'UTC'): Carbon
{
return Carbon::instance((new CronExpression(
sprintf('%s %s %s %s %s', $minute, $hour, $dayOfMonth, $month, $dayOfWeek)
- ))->getNextRunDate(now('UTC')));
+ ))->getNextRunDate(now($timezone)))->setTimezone('UTC');
}
public static function checked(string $name, mixed $default): string
diff --git a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php
index 9308d4ae3..229289c49 100644
--- a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php
+++ b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php
@@ -75,7 +75,7 @@ class ScheduleController extends ClientApiController
'cron_minute' => $request->input('minute'),
'is_active' => (bool) $request->input('is_active'),
'only_when_online' => (bool) $request->input('only_when_online'),
- 'next_run_at' => $this->getNextRunAt($request),
+ 'next_run_at' => $this->getNextRunAt($request, $request->user()->timezone ?? 'UTC'),
]);
Activity::event('server:schedule.create')
@@ -131,7 +131,7 @@ class ScheduleController extends ClientApiController
'cron_minute' => $request->input('minute'),
'is_active' => $active,
'only_when_online' => (bool) $request->input('only_when_online'),
- 'next_run_at' => $this->getNextRunAt($request),
+ 'next_run_at' => $this->getNextRunAt($request, $request->user()->timezone ?? 'UTC'),
];
// Toggle the processing state of the scheduled task when it is enabled or disabled so that an
@@ -188,7 +188,7 @@ class ScheduleController extends ClientApiController
*
* @throws DisplayException
*/
- protected function getNextRunAt(Request $request): Carbon
+ protected function getNextRunAt(Request $request, string $timezone = 'UTC'): Carbon
{
try {
return Utilities::getScheduleNextRunDate(
@@ -196,7 +196,8 @@ class ScheduleController extends ClientApiController
$request->input('hour'),
$request->input('day_of_month'),
$request->input('month'),
- $request->input('day_of_week')
+ $request->input('day_of_week'),
+ $timezone
);
} catch (Exception) {
throw new DisplayException('The cron data provided does not evaluate to a valid expression.');
diff --git a/lang/en/server/schedule.php b/lang/en/server/schedule.php
index be0ae8d7b..1e2679f10 100644
--- a/lang/en/server/schedule.php
+++ b/lang/en/server/schedule.php
@@ -29,7 +29,8 @@ return [
'enabled' => 'Enable Schedule?',
'enabled_hint' => 'This schedule will be executed automatically if enabled.',
- 'cron_body' => 'Please keep in mind that the cron inputs below always assume UTC.',
+ 'timezone' => 'Timezone',
+ 'cron_body' => 'The cron inputs below use your timezone (:timezone).',
'cron_timezone' => 'Next run in your timezone (:timezone): :next_run ',
'invalid' => 'Invalid',