Expand my Community achievements bar.

AEM Cloud Sling Job cron time for locations that follow daylight saving

Avatar

Level 2

Hi All,

We have currently migrating from AEM 6.5 to AEM cloud.
As the AEM cloud uses UTC time (and that can not be changed), when using cron expessions - we have scheduled it in UTC time so that it executes in the desired time in our timezone.
Ex: if we have to run a job at 10AM Pacific time (Seattle) --> we have used a cron expression (scheduler expression) to execute at 6PM UTC (as pacific time currently is UTC-8)

Question: People who moved to AEM cloud, how are you working with Daylight saving time for cron? Pacific time is UTC-8 for few months and UTC-7 for few months. How do you get a job to execute as a specific time with or without daylight saving.

 

Please let me know how can this be achieved or any alternatives you have used.

Thanks
Dinesh

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

2 Replies

Avatar

Community Advisor

Hi @Dinesh_A ,

You can try to implement your own custom logic which will read these cron expression and apply DST in it.
Try to customize the cron expression in your java code, something like below:

TimeZone zone = TimeZone.getTimeZone("America/New_York");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);

System.out.println(format.format(new Date()));

 

 

-Tarun

Avatar

Level 4

You could try something like the following: we use an OSGi configuration to specify the time zone, hour, and minute for the job. When the component activates, it converts the local time to UTC, considering daylight saving time ensuring the job runs at the correct local time. The job is then scheduled using the Sling Scheduler with the converted UTC time. Hopefully this approach should simplify handling daylight saving time changes for your scheduled jobs in AEM.

 

First create an OSGI configuraiton to store the time zone information.

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "Scheduler Configuration")
public @interface SchedulerConfig {

    @AttributeDefinition(name = "Time Zone", description = "Time zone for scheduling")
    String timeZone() default "America/Los_Angeles";

    @AttributeDefinition(name = "Hour", description = "Hour of the day (0-23)")
    int hour() default 10;

    @AttributeDefinition(name = "Minute", description = "Minute of the hour (0-59)")
    int minute() default 0;
}

 Then create a Job to use Java's ZoneId and ZonedDateTime classes to handle the conversion.

package com.example.core.schedulers;

import com.example.core.config.SchedulerConfig;
import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.ZoneId;
import java.time.ZonedDateTime;

@Component(immediate = true, service = Runnable.class)
@Designate(ocd = SchedulerConfig.class)
public class MyScheduledJob implements Runnable {

    private static final Logger LOG = LoggerFactory.getLogger(MyScheduledJob.class);
    private static final String JOB_NAME = "com.example.core.schedulers.MyScheduledJob";

    @reference
    private Scheduler scheduler;

    private String timeZone;
    private int hour;
    private int minute;

    @activate
    protected void activate(SchedulerConfig config) {
        this.timeZone = config.timeZone();
        this.hour = config.hour();
        this.minute = config.minute();
        scheduleJob();
    }

    @deactivate
    protected void deactivate() {
        scheduler.unschedule(JOB_NAME);
        LOG.info("Scheduled job deactivated");
    }

    private void scheduleJob() {
        ZoneId zoneId = ZoneId.of(timeZone);
        ZonedDateTime localTime = ZonedDateTime.now(zoneId).withHour(hour).withMinute(minute).withSecond(0);
        ZonedDateTime utcTime = localTime.withZoneSameInstant(ZoneId.of("UTC"));

        String cronExpression = String.format("0 %d %d * * ?", utcTime.getMinute(), utcTime.getHour());
        ScheduleOptions options = scheduler.EXPR(cronExpression);
        options.name(JOB_NAME);
        options.canRunConcurrently(false);
        scheduler.schedule(this, options);
        LOG.info("Scheduled job activated with cron expression: {}", cronExpression);
    }

    @Override
    public void run() {
        LOG.info("Executing scheduled job");
    }
}