Универсальный планировщик с использованием кварца - PullRequest
2 голосов
/ 08 января 2020

Я создаю универсальный планировщик, в котором пользователь может выбрать зону и запланировать задание в указанное время запуска. Я беру время начала в ZonedDateTime типе, а для кварца .startAt() требуется Дата , которая конвертируется следующим образом.

Текущий сценарий ios:

Cron Expression: 0 0/1 * * * ? (Every minute)
Server TimeZone: Asia/Kolkata 
Client TimeZone: [Europe/Paris] -4.5 

Начать стрельбу со следующей минуты после расписания, поскольку дата конвертируется в IST согласно серверу Чт 09 января 10:00:31 IST 2020. Пожалуйста, исправьте меня, если я ошибаюсь.

14:24:37.054 [XNIO-1 task-17] DEBUG c.c.a.s.impl.ScheduledJobServiceImpl - creating trigger for key 2104:  at date :2020-01-09T09:00:31Z[UTC] 
14:24:37.054 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - Request to create simple-trigger for minutes groupKey:1101, scheduleId: 2104, cron-expression: 0 0/1 * * * ?
14:24:37.055 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - Request to create date from ZonedDateTime in UTC based on localtime of user: 2020-01-09T09:00:31Z[UTC], zoneId: Europe/Paris
14:24:37.055 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - startTime to Instance: 2020-01-09T09:00:31Z
14:24:37.055 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - time at zone: 2020-01-09T10:00:31+01:00[Europe/Paris]
14:24:37.055 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - localDateTime at Zone: 2020-01-09T10:00:31
14:24:37.055 [XNIO-1 task-17] DEBUG c.c.a.s.util.JobScheduleCreator - DATE: Thu Jan 09 10:00:31 IST 2020

Cron Expression: 0 0/1 * * * ? (Every minute) 
Server TimeZone: Asia/Kolkata 
Client TimeZone: [Australia/Sydney] +5.5 

В четверг начнется пожар 20:00:41 IST 2020 что должно быть четверг 09 января 20:00:41 AET 2020. Верно?

14:24:48.185 [XNIO-1 task-18] DEBUG c.c.a.s.impl.ScheduledJobServiceImpl - creating trigger for key 2105:  at date :2020-01-09T09:00:41Z[UTC] 
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - Request to create simple-trigger for minutes groupKey:1101, scheduleId: 2105, cron-expression: 0 0/2 * * * ?
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - Request to create date from ZonedDateTime in UTC based on localtime of user: 2020-01-09T09:00:41Z[UTC], zoneId: Australia/Sydney
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - startTime to Instance: 2020-01-09T09:00:41Z
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - time at zone: 2020-01-09T20:00:41+11:00[Australia/Sydney]
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - localDateTime at Zone: 2020-01-09T20:00:41
14:24:48.186 [XNIO-1 task-18] DEBUG c.c.a.s.util.JobScheduleCreator - DATE: Thu Jan 09 20:00:41 IST 2020

Вопрос:

Как сказано в этих ответ , Для Date Текущий часовой пояс JVM по умолчанию применяется на лету. . Таким образом, невозможно преобразовать IST в AET/ECT! Это с датой? Поэтому я думаю, что мне нужно изменить реализацию создания триггера, которая в настоящее время занимает .startAt() в единственном формате **Date**. Есть ли другой способ указать время начала в других форматах при создании триггера?

createTrigger (String groupKey, ScheduledJob scheduleJob)

public CronTrigger createTrigger(String groupKey, ScheduledJob scheduledJob) {

        Date startDate = createDatefromZonedDateTime(scheduledJob.getScheduledStartTime(), scheduledJob.getZoneId());

        return newTrigger()
            .withIdentity(scheduledJob.getId().toString(),groupKey)
            .withDescription(scheduledJob.getZoneId())
            .withSchedule(CronScheduleBuilder.cronSchedule(scheduledJob.getCronExpression()).inTimeZone(TimeZone.getTimeZone(scheduledJob.getZoneId()))) 
            .startAt(startDate)
            .build();
    }

createDatefromZonedDateTime (ZonedDateTime startTime, String zoneId)

private Date createDatefromZonedDateTime(ZonedDateTime startTime, String zoneId) {

        log.debug("Request to create date from ZonedDateTime in UTC based on localtime of user: {}, zoneId: {}",startTime, zoneId);

        Instant utc = startTime.toInstant();
        log.debug("startTime to Instance: {}",utc);

        ZonedDateTime timeAtZone = utc.atZone(ZoneId.of(zoneId));
        log.debug("time at zone: {}",timeAtZone);

        LocalDateTime localDateTimeAtZone = timeAtZone.toLocalDateTime();
        log.debug("localDateTime at Zone: {}",localDateTimeAtZone);

        Date dateZone = Date.from(localDateTimeAtZone.atZone(ZoneId.systemDefault()).toInstant());
        log.debug("DATE: "+dateZone);

        return dateZone;
   }

ОБНОВЛЕНИЕ:

Чтобы преобразовать дату из IST в ECT или определенную пользователем зону, я нашел TimeZone.setDefault(TimeZone.getTimeZone(zone));, но это не рекомендованный рекомендуемый способ . Даже если я его использую, в разных зонах будет несколько заданий, и значение .setDefault будет заменено новым.

Другая идея состоит в том, чтобы динамически изменять DatePicker на основе выбранной пользователем зоны в angular и на основе значения мы преобразуем его в зону сервера и планируем его с датой зоны сервера и устанавливаем пользовательское значение зона в .withSchedule(CronScheduleBuilder.cronSchedule(scheduledJob.getCronExpression()).inTimeZone(TimeZone.getTimeZone(scheduledJob.getZoneId()))). Это правильный способ сделать это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...