Run a task in a different interval during weekend using Spring Scheduler and Custom Trigger

Run a task in a different interval during weekend.

Instead of defining fixed interval to run a task every 1 minute (as shown in example below) using @Scheduled, we can customize Spring Task Scheduler to schedule job with a custom trigger to run the tasks in different schedule depending on business logic. 

@Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES)
void job1() {
System.out.println("Running job1 - this won't run on weekend");
}

 

For example, we can do the following to run the task every 15 minute instead of 1 minute during weekends. Here we are registering a task job1 with TaskScheduler with a CustomTrigger.

The CustomTrigger implements Spring's Trigger interface and overrides nextExecution() method to do business logic to find the interval on which the task should run. For the example purpose we are running tasks less often (every 15 minute) during weekend.


DayOfWeek day = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CST"))).getDayOfWeek();
Duration nextSchedulePeriod = WORKDAY_INTERVAL;

/*
* Run the task every 15 minute often during weekend
*/

if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
nextSchedulePeriod = WEEKEND_INTERVAL;
}
return new PeriodicTrigger(nextSchedulePeriod).nextExecution(ctx);



import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.support.PeriodicTrigger;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;

@Configuration
class CustomTaskScheduler implements InitializingBean {

static final Duration WORKDAY_INTERVAL = Duration.ofMinutes(1);
static final Duration WEEKEND_INTERVAL = Duration.ofMinutes(15);

@Autowired
TaskScheduler taskScheduler;


@Override
public void afterPropertiesSet() {
taskScheduler.schedule(this::job1, new CustomTrigger());
// schedule more tasks
}

void job1() {
System.out.println("Running job1 - this won't run on weekend");
}


static class CustomTrigger implements Trigger {
/**
* Determine the next execution time according to the given trigger context.
*/
@Override
public Instant nextExecution(TriggerContext ctx) {
DayOfWeek day = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CST"))).getDayOfWeek();
Duration nextSchedulePeriod = WORKDAY_INTERVAL;

/*
* Run the task every 15 minute often during weekend
*/

if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
nextSchedulePeriod = WEEKEND_INTERVAL;
}
return new PeriodicTrigger(nextSchedulePeriod).nextExecution(ctx);
}


}

}

Append a file into existing ZIP using Java

Need to modify a text file inside a ZIP without extracting the whole archive to disk? In this post, I’m going to show you how to do exactly that with a pure‑Java approach. The snippet opens in.zip, streams through its entries, and for the one named abc.txt it reads the content, replaces key1=value1 with key1=val2, appends a timestamp, and writes the updated bytes. Every other entry is copied byte‑for‑byte unchanged into a fresh out.zip. The logic relies on java.util.zip.ZipFile for reading and ZipOutputStream for writing, completely avoiding temporary files. I’ve also included a small helper isToString that converts an InputStream to a String via a ByteArrayOutputStream. One thing to keep in mind: the current implementation loads the file’s entire content into memory, so it’s perfect for small text files. If you’re dealing with larger data, a line‑by‑line streaming variant would be safer. Just drop this code into a ZipTests class, place in.zip next to it, and run it — you’ll get out.zip with your modifications ready to use.


import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.zip.ZipOutputStream;

public class ZipTests {

public static void main(String[] args) throws Exception {
var zipFile = new java.util.zip.ZipFile("in.zip");
final var zos = new ZipOutputStream(new FileOutputStream("out.zip"));
for (var e = zipFile.entries(); e.hasMoreElements(); ) {
var entryIn = e.nextElement();
System.out.println("Processing entry " + entryIn.getName());

// Set the next entry before writing any data to it
zos.putNextEntry(entryIn);

if (entryIn.getName().equalsIgnoreCase("abc.txt")) {
// Read existing content, replace a key, and append a timestamp

String content = isToString(zipFile.getInputStream(entryIn));
content = content.replaceAll("key1=value1", "key1=val2");
content += LocalDateTime.now() + "\r\n";

byte[] buf = content.getBytes();
zos.write(buf, 0, buf.length);
} else {
// For all other entries, stream the bytes unchanged
var inputStream = zipFile.getInputStream(entryIn);
byte[] buf = new byte[9096];
int len;
while ((len = inputStream.read(buf)) > 0) {
zos.write(buf, 0, len);
}

}
zos.closeEntry();
}
zos.close();
}

static String isToString(InputStream stringStream) throws Exception {
var result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int length; (length = stringStream.read(buffer)) != -1; ) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8);
}

}

Spring Boot - get Trace and Span ID programmatically

 Autowire Tracer tracer

and get traceId and spanId from current Span


Span
span = tracer.currentSpan();
span.context().traceId() //trace ID span.context().spanId() //span ID