Programming time-controlled events that run from one day to the next can be tricky. Starting something when the time is 22:00 and stopping it when the time is 02:00 takes a lot of care. It can be particularly difficult if you want the program logic to work even if the controller restarts in the middle of the event due to a power failure.

Here's one way to make it work. I use it to switch lights on and off when I am away from home. The trick is to use a variable to hold the time (in minutes) that extends the day up until the next dawn - so the day is effectively longer than 24 hours!

100 IF Time of Day is > 00:00 // On every pass,
101 THEN Load Data to: Variable-#0-Temp // get the
102 ELSE Load Data to: Variable-#0-Temp // time of day.
103 IF Variable-#0-Temp is NOT = Variable-#10-TOD // New minute?
104 ELSE Skip to line xxx // No - bypass timed event logic.
105 THEN Variable-#10-TOD = Variable-#0-Temp // Yes - save the time
106 THEN Variable-#11-XTOD = Variable-#0-Temp // for later tests.
107 IF Time of Day is < Sunrise offset 0 minutes // If nightime,
108 THEN Variable-#11-XTOD + 1440 // offset for previous 24 hours.
109 //
110 If Variable-#11-XTOD becomes > 1319 // When its 22:00,
111 THEN X-10-I1-Flood, Turn On // turn Flood light on.
112 If Variable-#11-XTOD becomes > 1559 // When its 02:00,
113 THEN X-10-I1-Flood, Turn OFF // turn Flood light off.
114 If Variable-#11-XTOD becomes > 1439 // When its midnight,
115 THEN X-10-I2-Office, Turn On // turn Office light on.
116 If Variable-#11-XTOD becomes > 1499 // When its 01:00,
117 THEN X-10-I2-Office, Turn OFF // turn Office light off.
..
.. Convert and display time from Variable-#10-TOD
.. and other code that runs every minute.
..
xxx

The normal time is saved in variable TOD . Variable XTOD contains the same as TOD between sunrise and midnight but between midnight and dawn it is offset by 24 hours (1440 minutes). Tests for times after midnight and before sunrise just need to have 1440 added to them.

In practice, the timing of security lights should have some variablility for the time of sunset and maybe a random element. So it would be better to replace the fixed event times in lines 110, 112, 114 and 116 using variables that were pre-loaded with appropriate times.

110 If Variable-#11-XTOD becomes > Variable-#40-Sec1
..
112 If Variable-#11-XTOD becomes > Variable-#41-Sec2
..
etc.

The event trigger times could be loaded once per day with code like this:

050 IF Day of Month is NOT = Variable-#12-DOM // New day?
051 ELSE Skip to line yyy // No - bypass daily code.
052 THEN Load Data to: Variable-#12-DOM // Yes - save the day
053 THEN Load Data to: Variable-#13-Vary // and
054 THEN Variable-#13-Vary * 11 // calculate a
055 THEN Variable-#13-Vary % 30 // psuedo-random number
056 THEN Variable-#13-Vary - 15 // from -15 to +14
057 IF Time of Day is > Sunset offset 0 minutes // Get todays
058 THEN Load Data to: Variable-#14-Sunset // sunset
059 ELSE Load Data to: Variable-#14-Sunset // time.
060 If Day of Month is > 0 // Always..
061 THEN Variable-#40-Sec1 = Variable-#14-Sunset // Sec1 time is sunset
062 THEN Variable-#40-Sec1 + 60 // plus one hour
063 THEN Variable-#40-Sec1 + Variable-#13-Vary // with added variance.
064 THEN Variable-#41-Sec2 = Variable-#40-Sec1 // Sec2 time is
065 THEN Variable-#41-Sec2 + 180 // Sec1 time plus three hours
066 THEN Variable-#41-Sec2 - Variable-#13-Vary // with subtracted variance.
..
etc.
..
yyy

The code calculates a simple but useful psuedo-random number by multiplying the day of the month by 11 (a prime number), using the modulus operator (%) to scale it from 0-29 and then subtracting 15 so it will range from -15 to +14 minutes. This is saved in variable Vary and then used to adjust the "trigger" times.

The individual trigger times (Sec1, Sec2, etc) are calculated by adding offsets to today's sunset time. The value in Vary can optionally be added or subtracted to give some variation to the times each day.

It isn't necessary to worry about a trigger time crossing midnight as long as it can never be later than sunrise.