Я создаю универсальный планировщик, в котором пользователь может выбрать зону и запланировать задание в указанное время запуска. Я беру время начала в 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())))
. Это правильный способ сделать это?