How to check if today is between two static dates

I want to define multiple date blocks (school holidays) and compare now with those dates. Something like this:

rule "regelTestsDel2" when
	Item del2 received command ON
then	
	val startDate = new DateTime(2025, 12, 23)
	val endDate = new DateTime(2026, 01, 06)

	if (now() >= startDate && now() <= endDate) {
		logInfo("DatumCheck", "Holiday")
	} else {
		logInfo("DatumCheck", "Not holiday")
	}
	
end
  • Platform information:
    • Hardware: Raspberry 5
    • OS: Openhabian
    • openHAB version: 4.2.1

It was a long time since I used rules DSL, so not sure if there even is a DateTime class available? But LocalDate should work here:

rule "regelTestsDel2" when
	Item del2 received command ON
then
        val today = LocalDate.now()	
	val startDate = LocalDate.of(2025, 12, 23)
	val endDate = LocalDate.of(2026, 01, 06)

	if (today.isAfter(startDate) && today.isBefore(endDate)) {
		logInfo("DatumCheck", "Holiday")
	} else {
		logInfo("DatumCheck", "Not holiday")
	}
	
end

It does but it’s ZonedDateTime.

But using that instead of LocalDate doesn’t really add anything except additional complexity so what you show is probably the easiest approach.

In JS it’s a little simpler:

if(time.toZDT().isBetweenDates(time.LocalDate(2025, 12, 23), time.LocalDate(2026, 01, 06)) {
  console.info("Holiday");
}
else {
  console.info("Not Holiday");
}

I might submit a PR to make dates work the same as times. For example, you can test if now is between two times using:

if(time.toZDT().isBetweenTimes('08:00', '22:00')) {
  console.info("Day");
}
else {
  console.info("Night");
}

Blockly also supports “isBetween” operations like this.

Or just use blockly :wink:

This would need to also check if today == startdate as well as today == enddate

In JRuby, all date/time operations are so simple and nice to write and to read.

logger.info Date.today.between?("2025-12-23", "2026-01-06") # include year

# Checking just month and date. Crossing year works as expected 
logger.info Date.today.between?("12-23", "01-06")

This between? method is available, in JRuby, for just about any date/time related stuff, including Java’s ZonedDateTime, LocalDate, LocalTime, MonthDay, Month, Duration, etc, and Ruby’s Time, Date, etc.

Furthermore you can use ranges too, and in ranges, you can use two dots (includes the end range), or three dots (excludes the end range), begin-less range, and end-less range

logger.info 3.seconds.between?(2.seconds..3.seconds) # => true
logger.info 3.seconds.between?(2.seconds...3.seconds) # => false

You can also write it as following if you prefer, but it’s not as nice as using between?

today = Time.now # or ZonedDateTime.now
logger.info today >= Time.new(2025, 12, 23) && today <= Time.new(2026, 01, 06)

Lastly, if you want to use Ephemeris, you can enter your Holidays into a custom ephemeris file and after that, you simply do

holiday_file! OpenHAB::Core.config_folder / "holidays/my_holiday.xml"

if Time.now.holiday? # This can be #ZonedDateTime, or even a DateTimeItem
  logger.info "Today is a holiday"
else
  logger.info "Today is not a holiday"
end

#It works for a DateTime Item too!

if MyDateTimeItem.holiday?
  logger.info "MyDateTimeItem contains #{MyDateTimeItem.state} which is a holiday"
end

Is that ‘true’ for 12/23/2025 and for 1/6/2026? That is, inclusive? ‘Between’ is ambiguous to me but maybe not to everyone else? Probably it is inclusive, just not sure.

I’m not sure what you mean be inclusive in this context. But the test is whether time.toZDT() is after the start date and before the end date so 12/23/2025 would return false.

You can see the code here: time.js - Documentation

/**
 * Tests whether `this` time.ZonedDateTime is between the passed in start and end.
 * However, the function only compares the date portion of the three, ignoring the time portion.
 *
 * @param {*} start starting date, anything supported by {@link time.toZDT}
 * @param {*} end ending date, anything supported by {@link time.toZDT}
 * @returns {boolean} true if `this` is between start and end
 */
time.ZonedDateTime.prototype.isBetweenDates = function (start, end) {
  const startDate = toZDT(start).toLocalDate();
  const endDate = toZDT(end).toLocalDate();
  const currDate = this.toLocalDate();
  return currDate.isAfter(startDate) && currDate.isBefore(endDate);
};

And looking at the docs for isBefore and isAfter on the js joda library: LocalDate | js-joda

Checks if this date is before the specified date.

This checks to see if this date represents a point on the local time-line before the other date.

LocalDate a = LocalDate.of(2012, 6, 30);
LocalDate b = LocalDate.of(2012, 7, 1);
a.isBefore(b) == true
a.isBefore(a) == false
b.isBefore(a) == false

@jswim788’s question is about whether a date equal to one of the boundaries would return true.

In jruby the answer is yes.

In jsscripting, it seems that the answer is no:
return currDate.isAfter(startDate) && currDate.isBefore(endDate); given that a.isBefore(a) == false

1 Like

Great examples and paths. As I am a lazy developer, this is the perfect solution for me:

    val today = LocalDate.now()	
	val startDate = LocalDate.of(2025, 01, 15)
	val endDate = LocalDate.of(2025, 01, 16)

	
	if (today.isAfter(startDate.minusDays(1)) && today.isBefore(endDate.plusDays(1))) {
		logInfo("DatumCheck", "Holiday")
	} else {
		logInfo("DatumCheck", "Not holiday")
	}

Thank you all for helping me.