Saltar al contenido

Java Quartz-Scheduler a través de TimeZone

No olvides que en las ciencias un problema casi siempere suele tener diferentes soluciones, por lo tanto te compartiremos lo más óptimo y mejor.

Solución:

Creo que encontré la solución, probé y funciona hasta que se demuestre lo contrario;)

Recup My server se ejecuta en una zona horaria específica (es decir, Europa/Roma)

Si un usuario en Pacific/Honolulu TZ desea programar un trabajo que comienza el domingo 27 de enero de 2013 a las 3:00 p. m. y finaliza el jueves 31 de enero de 2013 a las 9:00 p. 22:55 (0 0/5 14-22 * * ?) la forma correcta es la siguiente:

  • establezca la zona horaria del usuario en el método inTimeZone en CronScheduleBuilder
  • adapte a la hora del servidor las fechas startAt y endAt convirtiendo de Pacífico/Honolulu a Europa/Roma

Código de muestra:

// Begin User Input
String userDefinedTZ = "Pacific/Honolulu"; // +11

int userStartYear = 2013;
int userStartMonth = Calendar.JANUARY;
int UserStartDayOfMonth = 27;
int userStartHour = 15;
int userStartMinute = 0;
int userStartSecond = 0;

int userEndYear = 2013;
int userEndMonth = Calendar.JANUARY;
int UserEndDayOfMonth = 31;
int userEndHour = 21;
int userEndMinute = 0;
int userEndSecond = 0;
// End User Input


Calendar userStartDefinedTime = Calendar.getInstance();
// set start schedule by user input
userStartDefinedTime.set(userStartYear, userStartMonth, UserStartDayOfMonth, userStartHour, userStartMinute, userStartSecond);

Calendar userEndDefinedTime = Calendar.getInstance();
// set end schedule by user input
userEndDefinedTime.set(userEndYear, userEndMonth, UserEndDayOfMonth, userEndHour, userEndMinute, userEndSecond);


CronTrigger trigger = newTrigger()
  .withIdentity("name", "group")
  .withSchedule(
    // define timezone for the CronScheduleBuilder
    cronSchedule("0 0/5 14-22 * * ?").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu"))
  )
  // adapt user start date to server timezone
  .startAt( convertDateToServerTimeZone(userStartDefinedTime.getTime(), userDefinedTZ) )
  // adapt user end date to server timezone
  .endAt( convertDateToServerTimeZone(userEndDefinedTime.getTime(), userDefinedTZ) )
  .build();

Utilidad para convertir fechas en base a tz:

public Calendar convertDateToServerTimeZone(Date dateTime, String timeZone) 
    Calendar userDefinedTime = Calendar.getInstance();
    userDefinedTime.setTime(dateTime);
    if(!TimeZone.getDefault().getID().equalsIgnoreCase(timeZone)) 
    System.out.println        ("original defined time: " + userDefinedTime.getTime().toString() + " on tz:" + timeZone);
    Calendar quartzStartDate = new GregorianCalendar(TimeZone.getTimeZone(timeZone));
    quartzStartDate.set(Calendar.YEAR, userDefinedTime.get(Calendar.YEAR));
    quartzStartDate.set(Calendar.MONTH, userDefinedTime.get(Calendar.MONTH));
    quartzStartDate.set(Calendar.DAY_OF_MONTH, userDefinedTime.get(Calendar.DAY_OF_MONTH));
    quartzStartDate.set(Calendar.HOUR_OF_DAY, userDefinedTime.get(Calendar.HOUR_OF_DAY));
    quartzStartDate.set(Calendar.MINUTE, userDefinedTime.get(Calendar.MINUTE));
    quartzStartDate.set(Calendar.SECOND, userDefinedTime.get(Calendar.SECOND));
    quartzStartDate.set(Calendar.MILLISECOND, userDefinedTime.get(Calendar.MILLISECOND));
    System.out.println("adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime().toString());
    return quartzStartDate;
     else 
    return userDefinedTime;
    

== COMIENZO DE LA ACTUALIZACIÓN 2012-01-24 ==

Utilidad basada en cuarzo para convertir fechas basadas en tz usando DateBuilder:

public Calendar convertDateToServerTimeZone(Date dateTime, String timeZone) 
    Calendar userDefinedTime = Calendar.getInstance();
    userDefinedTime.setTime(dateTime);
    if(!TimeZone.getDefault().getID().equalsIgnoreCase(timeZone)) 
      System.out.println("original defined time: " + userDefinedTime.getTime().toString() + " on tz:" + timeZone);

      Date translatedTime = DateBuilder.translateTime(userDefinedTime.getTime(), TimeZone.getDefault(), TimeZone.getTimeZone(timeZone));

      Calendar quartzStartDate = new GregorianCalendar();
      quartzStartDate.setTime(translatedTime);
      System.out.println("adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime().toString());
      return quartzStartDate;
     else 
      return userDefinedTime;
    

== FIN DE LA ACTUALIZACIÓN 2012-01-24 ==

Entonces en mi servidor Europe/Rome Quartz, este trabajo está programado para comenzar desde el lunes 28 de enero a las 02:00:00 CET de 2013 hasta el viernes 01 de febrero a las 08:00:00 CET de 2013 y disparar cada cinco minutos todos los días de 01:00 a. m. a 08:55 p. m.

Al crear sus fechas para las horas de inicio y finalización, también especifique la zona horaria (en java.util.Calendar, o formato de fecha string, u org.quartz.DateBuilder) antes de instanciar la fecha. Luego, el cuarzo almacena la fecha en milisegundos desde el 1 de enero de 1970 en UTC en esa zona horaria en particular y, por lo tanto, cuando cambia la zona horaria del servidor, el disparador no se ve afectado.

Si para ti ha sido provechoso este artículo, agradeceríamos que lo compartas con más juniors y nos ayudes a dar difusión a nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *