Sadly, openHAB scheduling is awful too.
More difficult than you think. For that reason I think most users rely on the CalDav binding and use their calendar software to schedule these events.
That being said, you have a number of options inside openHAB.
As Michael indicates, event based scheduling is easy and it’s basically who OH works. You can write Rules that trigger when certain events occur (e.g. a Temperature Item changes) and then write code that does what it’s supposed to do based on the actual temp reading.
For things that occur on a regular schedule and don’t need to be adjusted manually (i.e. if you need to change it you can change code) there is cron triggered Rules. These use a Quartz Cron expression (unlike regular cron it includes a seconds field) and will trigger the Rule based on the expression. You can have everything from as simple as every minute to something as complicated as the first Monday of the month. But to adjust the expression, you need to modify code.
There is the Time of Day DP: Design Pattern: Time Of Day, which sets up a time driven state machine that can be used as events and states to make decisions within Rules. So rather than needing to check if it’s after sunrise and before 09:00, that calculation is performed in the ToD Rule and you just need to check if the vTimeOfDay Item is “MORNING”. Or you can trigger a Rule using
Item vTimeOfDay changed to MORNING.
There is a new capability in OH 2.5 called Ephemeris. This lets you define day types: weekend, workday, bank holiday, etc. and provides some Actions that let you do things like
daysUntil("Christmas") and make decisions in a Rule.
I have a version of the Time of Day DP submitted to the Scripted Automation Helper Libraries that lets you establish a different set of time of day states based on the type of day, so your morning can start at 08:00 on a bank holiday instead of at sunrise, for example.
Sometimes, once you are in a Rule you will want something to happen a certain about of time after an event occurs. For example, Design Pattern: Motion Sensor Timer which keeps a light on until a certain amount of time after the last motion sensor event. For this we use Timers and/or the Expire binding.
If you look at the alarm clock examples linked to above, you will see that how they work is the user adjusts the time in the sitemap using two separate Items, one for hour and one for minute. Then a Timer is set up to trigger at that time every day.
Another use case is when you have something like a sprinkler system where one zone comes on for a certain amount of time followed by the next for a different amount of time and so on. In this case you can use timers as described in Design Pattern: Cascading Timers. So, for example, you could use a cron triggered Rule or an event from the Alarm Clock examples or Time of Day DP to start the cascade and then the cascade drives itself to completion.
The weakest point is entry of the date times for all of this. We have to work around that limitation. But once you get past that, there actually is a lot of powerful scheduling tools available to you, but you have to do it in Rules code.