Need help with setting and calculating "time of day"

Having worked with OpenHAB since 2015 I have now decided to migrate to HA. Main reasons are Lovelace with all cards and add-ons, the extremely professional documentation and that OH3 will introduce some breaking changes that I cannot accept.

Enough said, I am still quite a noob, especially when it comes to writing automations that are time dependant. One major building block in my automation is a sensor that reports the time of day as a string. Here are the requirements:

From midnight to a fixed time (06:30) it is NIGHT
From 06:30 to 07:15 it is EARLY_MORNING
From 07:15 to Sunrise it is MORNING
From Sunrise to Sunset it is DAY
From Sunset to Dusk it is AFTERNOON
From Dusk to 23:30 it is EVENING
From 23:30 to midnight it is NIGHT

Here in Sweden, the sun might rise in the summer already before 06:30 so in that case the time of day goes directly from NIGHT to DAY or from EARLY MORNING to DAY

This is the way it is done in OpenHAB:

val logName = "timeofday"

	rule "Calculate time of day state"
  	System started or
  		Time cron "0 1 0 * * ? *" or
		Time cron "0 30 6 * * ? *" or
  		Time cron "0 15 7 * * ? *" or
  		Channel 'astro:sun:ff35f917:rise#event' triggered START or
  		Channel 'astro:sun:ff35f917:set#event' triggered END or
  		Channel 'astro:sun:ff35f917:civilDusk#event' triggered END or
  		Time cron "0 30 23 * * ? *" 
  		val earlymorning_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(1050)  // 06:30 Start of early morning
		logInfo(logName, "earlymorning_start" + earlymorning_start.toString)
		val morning_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(1005) // 07:15 Start of morning
  		logInfo(logName, "morning_start" + morning_start.toString)
  		val night_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(30) // 23:30 Start of night
  		logInfo(logName, "night_start" + night_start.toString)

		// Convert the Astro Items to Joda DateTime  
		val day_start = new DateTime(Solna_AstroSunData_Rise_StartTime.state.toString)
  		logInfo(logName, "day_start" + day_start)
  		val afternoon_start = new DateTime(Solna_AstroSunData_Set_EndTime.state.toString)
  		logInfo(logName, "afternoon_start" + afternoon_start)
 		 val evening_start = new DateTime(Solna_AstroSunData_CivilDawn_EndTime.state.toString)
  		logInfo(logName, "evening_start" + evening_start)
  		var curr = "UNKNOWN"

  	switch now {
        case now.isBefore(earlymorning_start):							  		curr = "NIGHT"
		case now.isAfter(earlymorning_start) && now.isBefore(morning_start):	curr = "EARLYMORNING"
        case now.isAfter(morning_start) && now.isBefore(day_start):       		curr = "MORNING"
        case now.isAfter(day_start) && now.isBefore(afternoon_start):     		curr = "DAY"
        case now.isAfter(afternoon_start) && now.isBefore(evening_start): 		curr = "AFTERNOON"
        case now.isAfter(evening_start) && now.isBefore(night_start):     		curr = "EVENING"
        case now.isAfter(night_start):     								  		curr = "NIGHT"

   		logInfo(logName, "Current time of day is now " + curr)


I am just not skilled enough to translate this into Ninja? vocabulary. If someone could help me to at least get started I would be eternally grateful.
As you see all times are calculated starting from the end of the day and then counting backwards.

1 Like