[Solved] Comparing DateTime Items

I’d like to see if a date from CalDAV is due today.

There are these items:

DateTime    tDateToday   "Today [%1$td.%1$tm.%1$tY]"  { ntp="Europe/Berlin:de_DE" }

and

DateTime    tDate1 "date1: [%1$td.%1$tm. %1$tH:%1$tM]" { caldavPersonal="calendar:myCalendar type:EVENT eventNr:1 value:START" }
DateTime    tDate2 "date2: [%1$td.%1$tm. %1$tH:%1$tM]" { caldavPersonal="calendar:myCalendar type:EVENT eventNr:2 value:START" }

All items are updated and have valid values. This was checked using an extra sitemap for testing.

Now I’d like to set up a rule that checks if tDate1 is set for today or maybe tomorrow.
So effectively I’d like to display all dates scheduled for today in the sitemap and all dates due tomorrow in another frame of that sitemap.
Also, a passed date should still be displayed (e.g. an appointment scheduled for 9:00 today should still be displayed in the evening) just like in a real calender made from paper.

There are quite a few examples but I didn’t get any of them to work as they seem to check the time now instead of today’s date. This also has the effect that today’s dates are deleted from the list because they are elapsed.

Also different approaches are used like
isAfter, isBefore
or
(time1 > time2)
which is quite confusing and hard to get to run at all.

So how do I check if the items above
tDate1 and tDate2
are scheduled for today / tomorrow and keep them in the sitemap all day?

I’ll be happy to try out your suggestions. Maybe there’s even a working example.
Please specify the required include files as in the past it took me a lot of time to figure out what needs to be included.

Thank you very much!

Here are my findings:

  • CalDAV does not return past events. If those should be displayed some sort of persistence is required.
    For now I’m not gonna implement this. So only current and future events will be shown.
  • The start and end time of a day can be determined by using withTimeAtStartOfDay.
  • The start time of an event that’s scheduled for today must be within those boundaries.

With this I came up with the following rules which seem to work alright:

Items:

DateTime    tDateToday     "Today [%1$td.%1$tm.%1$tY]"        <calendar> { ntp="Europe/Berlin:de_DE" }
String      sNameDate1     "name: [%s]"                       <calendar> { caldavPersonal="calendar:myCalendar type:EVENT eventNr:1 value:NAME" }
DateTime    tTimeDate1     "time: [%1$td.%1$tm. %1$tH:%1$tM]" <calendar> { caldavPersonal="calendar:myCalendar type:EVENT eventNr:1 value:START" }
String      sNameTimeDate1 "name+time: [%s]"                  <calendar>
String      sTodayDate1    "today #1 [%s]"                    <calendar>

A rule that combines name and time:

rule "buildDate1"
    when
        Item sNameDate1 received update or
        Item tTimeDate1 received update
    then
        if ((sNameDate1.state != Undefined) && (sNameDate1.state != Uninitialized) &&
            (tTimeDate1.state != Undefined) && (tTimeDate1.state != Uninitialized)) {
                sNameTimeDate1.postUpdate(sNameDate1.state.format("%1$tH:%1$tM") + " - " + tTimeDate1.state.toString)
        }
end

The next rule checks if the event is scheduled for today:

rule "todayDate1"
    when
        Item tDateToday received update or
        Item sNameDate1 received update
    then
        if((tTimeDate1.state != Undefined) && (tTimeDate1.state != Uninitialized) &&
            now.withTimeAtStartOfDay.isBefore((tTimeDate1.state as DateTimeType).calendar.timeInMillis) &&
            now.withTimeAtStartOfDay.plusHours(24).isAfter((tTimeDate1.state as DateTimeType).calendar.timeInMillis) )
            sTodayDate1.postUpdate(sNameDate1.state.toString)

The rules use these imports:

import org.joda.time.*
import org.openhab.core.library.types.DateTimeType

The same scheme is repeated for all 4 sTodayDateX items.