You are here
Home > java >

Spring Scheduling Cron Expression

Spring Scheduling Cron ExpressionWhen we have a requirement where we need to run a task/job repeatedly after a particular time interval, we achieve this functionality by implementing Scheduling. For Java developers, Spring Framework makes it simple by offering Spring Scheduler. Moreover, Cron Expressions are the most widely used approach to achieve scheduling. Cron Expressions are very popular in Unix/Linux OS for scheduling. Spring framework also incorporates the same concept internally. Spring Framework offers us an API where we can utilize Cron expression to get the task scheduled. This article about ‘Spring Scheduling Cron Expression’ includes all the new improvements in Cron Expressions in Spring 5.3.

However, there are some other approaches to get our task scheduled using Spring/Spring Boot, but here in this article we will be focusing on Cron expressions only. Additionally, we will also talk about the improved Cron Expressions in Spring 5.3. There is a separate detailed article on Spring Boot Scheduling where we have already talked about other approaches including Scheduling fundamentals. Let’s discuss our topic ‘Spring Scheduling Cron Expression’ and its related concepts.

What is a Cron Expression?

A cron expression is a string consisting of six or seven subexpressions (fields) that describe individual details of the schedule. These fields, separated by white space, can contain any of the allowed values with various combinations of the allowed characters for that field. Below picture shows the fields in the expected order and allowed values with characters.

Note: As per the Spring Framework’s documentation, the allowed values for the field ‘day of week’ are 0-7. Here ‘0’ or ‘7’ both represent ‘Sunday’. Hence, below listings shows the clear mapping of days with numbers.

Spring Scheduling Cron Expression 0 = Sunday
1 = Monday
2 = Tuesday
3 = Wednesday
4 = Thursday
5 = Friday
6 = Saturday
7 = Sunday

Note: The previous versions and the latest Spring 6.0 supports six fields in the cron expression: second, minute, hour, day of month, month and day of week. The parse( ) method of CronExpression class provided by the Spring Framework says that if fields’ length is not equal to 6, you will face IllegalArgumentException. Below code snippet is from parse( ) method of CronExpression class. 

if (fields.length != 6) {
    throw new IllegalArgumentException(String.format(
         "Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression));
}

How To Write a Cron Expression?

Let’s understand the complete description of a cron expression, including each allowed characters and how to write a Spring Scheduling Cron Expression.

1) There are 6 Asterisks (* * * * * *) by default as a placeholder in cron expression as shown in the picture above. Further, each asterisk represents a value. These values can be assigned as Seconds, Minutes, Hours, Day Of Month, Month, Day Of Week respectively in the sequence.
Allowed values at proper place are also given in the picture above.

2) A Cron Expression can accept symbols : *  –   ,   /   ?   L   W  #

3) Comma denotes possible values separated by comma
For example, the expression “0 0 4,14 * * *” denotes ‘4:00:00AM and 2:00:00 PM every day’.

4) Dash (-) denotes a range, which means, considering all possible values between the range. Ranges of numbers are expressed by two numbers separated with a hyphen. The specified range is inclusive.

For example, the expression ”0 0 2-4 * * *” just denotes ‘execute given task every day 2:00:00AM, 3:00:00AM and 4:00:00AM’.

5) Asterisk(*) denotes any/every/all value

For example, the expression “0 0 * * * *” denotes ‘the top of every hour of every day’ or in simple terms ‘hourly’.

6) Forward slash(/) denotes a period of time

For example, the expression “0 0/30 2-4 * * *” denotes ‘2:00, 2:30, 3:00, 3:30, 4:00 and 4:30AM every day’.

7) Question mark(?) denotes any value like *, but it can be used for the ‘day of the month’ or ‘day of the week’ fields instead of an asterisk.

8) English names can also be used for the month and the day-of-week fields. Use the first three letters of the particular day of week or month (case does not matter). While writing a Spring Scheduling Cron Expression, it is advisable to use English names for the ‘day-of-week’ and ‘months’ instead of numbers, as they are self explanatory and also eliminates the chances of making mistakes.

For example, 11 = NOV and 5 = FRI

9) L: The ‘day of month’ and ‘day of week’ fields can contain an ‘L’ character, which stands for ‘last’, and has a different meaning in each field. In the ‘day of month’ field, L stands for ‘the last day of the month’. If followed by a negative offset i.e. ‘L-n’, it means ‘nth-to-last day of the month’. For example, L-3 = third-to-last day of the month. If followed by W i.e. ‘LW’, it means ‘the last weekday of the month’.

In the ‘day of week’ field, L stands for ‘the last day of the week’. If prefixed by a number or three-letter name i.e. ‘nL’ or ‘DDDL’, it means “the last day of week ‘n’ or ‘DDD’ in the month” respectively.

For example, 5L = last Friday of the month. TUEL = last Tuesday of the month.

10) W: The character ‘W’ is applicable to the ‘day of month’ only. The ‘day of month’ field can be ‘nW’, which stands for ‘the nearest weekday to day of the month n’.

For example, ‘1W’ stands for the ‘first weekday of the month’. ‘4W’ stands for the ‘fourth weekday of the month’. ‘LW’ stands for the ‘last weekday of the month’.

If n falls on Saturday, this returns the Friday. On the other hand, if n falls on Sunday, this returns the Monday.

11) #: The character ‘#’ is applicable to the ‘day of week’ only. The ‘day of week’ field can be ‘d#n’ or ‘DDD#n’, which stands for ‘the n-th day of week d or DDD in the month’.

For example, 5#3 = the third Friday in the month. WED#1 = the first Wednesday in the month.

12) C: The ‘C’ character is shorthand for “calendar” and is only allowed for the day-of-month and day-of-week fields. This means values are calculated against the associated calendar, if any. If no calendar is associated, then it is equivalent to having an all-inclusive calendar.

For example, a value of ‘5C’ in the day-of-month field means ‘the first day included by the calendar on or after the 5th’. A value of  ‘1C’ in the day-of-week field means ‘the first day included by the calendar on or after Sunday’.

The character ‘C’ is very rarely used and even doesn’t exist in Spring 5.3 improvements. Moreover, the new CronExpression class provided by Spring 5.3 is based on ‘java.time’ APIs in contrast to CronSequesnce class in older versions which was based on ‘java.util.Calendar’ APIs.

Where To Use Cron Expression In a Spring based Application?

Cron expressions are mostly used in Spring applications through the @Scheduled annotation. @Scheduled is a method level annotation applied at runtime to mark the method to be scheduled. Once we finalize the method where we require scheduling, we apply @Scheduled annotation on it with cron attribute. This ‘cron’ attribute accepts the cron expression. For example, below code snippet demonstrates the concepts of using Spring Scheduling cron expression with the @Scheduled annotation.

import java.time.LocalDateTime;
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 

@Component 
public class SchedulerService { 
   
   @Scheduled(cron = "15 * * * * *") 
   public void scheduledMethod() {
      System.out.println("Hello cron Scheduler Service: " +LocalDateTime.now()); 
   } 
}

Specifically, the cron expression in the above program indicates the execution of a task at every minute 15th second.

The CronExpression Class: Since Spring 5.3

The CronExpression class introduced in Spring 5.3 handles the cron expression. It replaces the CronSequenceGenerator (Deprecated Since Spring 5.3) class. CronSequenceGenerator class was based on ‘java.util.Calendar’ which has several known issues that none of the Spring team members felt comfortable solving. On the other hand, the new class CronExpression offers us to use the modern & superior ‘java.time’ APIs, solves the outstanding issues, and initiates new features as well.

If you want to play around with CronExpression yourself, you can create one through the static parse method. For example:

import org.springframework.scheduling.support.CronExpression;
import java.time.LocalDateTime;

var expression = CronExpression.parse("15 * * * * *");
var result = expression.next(LocalDateTime.now());
System.out.println(result);

In the code sample above,expression represents a cron expression that triggers 15 seconds past every minute. The parse( ) method takes the string with six space-separated time and date fields.

New Features as Corn Expression Improvements in Spring 5.3

Although we have already covered the new features & improvements of Spring Scheduling Cron Expression in the section ‘how to write a cron expression’ except macros, but we will specifically talk about it here in this section. These improvements are available in Spring Boot as well since Spring Boot 2.4.

Macros

Spring now supports the some macros, which represent commonly used sequences in order to improve readability. Even we can use these macros rather than writing the six-digit values. They will not only save your time, but also eliminate the chances of making mistakes. Below is the list of macros that we can use in our code in case of Spring 5.3 or later versions.

1) For Once a Year:    @yearly or @annually  in place of  “0 0 0 1 1 *”

2) For Once a Month: @monthly in place of  “0 0 0 1 * *”

3) For Once a Week:   @weekly in place of  “0 0 0 * * 0”

4) For Once a Day:     @daily or @midnight in place of  “0 0 0 * * *”

5) For Once an Hour: @hourly in place of  “0 0 * * * *”

Last Days (L)

The character ‘L’ stands for last. We can use this character in the ‘day of month’ and ‘day of week’ fields. Complete details on how to use this character are described in the section ”how to write a cron expression” of this article. Let’s take some examples:

Cron Expression Meaning

0 0 0 L * *

Last day of the month at midnight

0 0 0 L-2 * *

Second-to-last day of the month at midnight

0 0 0 * * 4L

Last Thursday of the month at midnight

0 0 0 * * MONL

Last Monday of the month at midnight

Weekdays (W)

The character ‘W’ stands for Weekdays. We can use this character in the ‘day of month’ field. Complete details on how to use this character are described in the section ”how to write a cron expression” of this article. Let’s see some examples:

Cron Expression Meaning

0 0 0 1W * *

First weekday of the month at midnight

0 0 0 LW * *

Last weekday of the month at midnight

Day of the Week in the Month (#)

The character ‘#’ is applicable to the ‘day of week’ only. The ‘day of week’ field can be ‘d#n’ or ‘DDD#n’, which stands for ‘the n-th day of week d or DDD in the month’. Let’s see some examples:

Cron Expression Meaning

0 0 0 ? * 5#3

The third Friday in the month at midnight

0 0 0 ? * SUN#1

The first Sunday in the month at midnight

Examples Of Spring Scheduling Cron Expression

Let’s clear our concepts of Spring Scheduling Cron Expression with some examples. Here, we will focus on the examples which come under the improved features of Spring Scheduling Cron Expression since Spring 5.3. Should you expect basic examples on Spring Scheduling Cron Expression with scheduling fundamentals, kindly visit the separate article on ‘Spring Boot Scheduling‘.

Ex#1) Write a Cron expression which should fire at 4:10 PM and at 4:24 PM every Monday in the month of FEB.

Ans. 0 10,24 16 ? FEB MON     or      0 10,24 16 ? 2 1

Ex#2) Write a Cron expression which should fire at 8:30 AM on the third Friday of every month.

Ans. 0 30 8 ? * FRI#3     or    0 30 8 ? * 5#3

Ex#3) Write a Cron expression which should fire at 10:15 PM on the 10th day of every month.

Ans. 0 15 22 10 * ?

Ex#4) Write a Cron expression which should fire every October 10 at 10:10 AM.

Ans. 0 10 10 10 10 ?     or     0 10 10 10 OCT ?

Ex#5) Write a Cron expression which should fire at 12 PM (noon) every 10 days every month, starting on the fifth day of the month.

Ans. 0 0 12 5/10 * ?

Ex#6) Write a Cron expression which should fire at 5:15 PM on the last day of every month.

Ans. 0 15 17 L * ?

Ex#7) Write a Cron expression which should fire at the third weekday of the month at 9:00 AM.

Ans. 0 0 9 3W * *

Ex#8) Write a Cron expression which should fire at the last Monday of the month at midnight.

Ans. 0 0 0 * * 1L     or      0 0 0 * * MONL

Ex#9) Write a Cron expression which should fire at the last weekday of the month at 9:59:59 AM.

Ans. 59 59 9 LW * *

Ex#10) Write a Cron expression which should fire at the second-to-last day of the month at midnight.

Ans. 0 0 0 L-2 * *

Ex#11) Write a Cron expression which should fire at the start of every New Year Day.

Ans. 0 0 0 1 1 ?

Ex#12) Write a Cron expression which should fire at the last day of the month at 6:00 PM.

Ans. 0 0 18 L * *

FAQ

What are the guidelines to use @Scheduled Annotation?

@Scheduled is a method level annotation applied at runtime to mark the method to be scheduled. Any method using @Scheduled needs to satisfy two conditions:

1) The annotated method should not have a return type. Otherwise the return value will be overlooked at runtime.

2) The annotated method should not accept any input parameters.

What are the improvements in cron expressions introduced with the Spring 5.3 release?

Spring 5.3 introduced improvements in the Spring Scheduling Cron Expression as shown below:

1) The CronExpression class introduced in Spring 5.3. It replaces the CronSequenceGenerator class.

2) Macros: Macros as an alternative to the six-digit values to make cron expression simple and easy to understand.

3) Three new characters in cron expressions : L, W, and  #

Conclusion

We have discussed the concepts of Spring Scheduling Cron Expression at length, including ample amounts of examples in this article. Moreover, we have also discussed improvements in Cron Expressions in Spring 5.3. After going through this article, you should be able to write a Spring Scheduling Cron Expression confidently. I hope, you will also apply the learned concepts in your project. Furthermore, if there will be more improvements in the future, we will also update the article accordingly. Please provide your comments in the comment box if any.

Source:

https://spring.io/blog/2020/11/10/new-in-spring-5-3-improved-cron-expressions

https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm

 

close

Leave a Reply

Top