or
Whenever I see time checks made like this it makes me shudder - sorry
For numerous reasons.
- none oft these solutions (nore does the original request state the exact bounds) do any explicit checks for "at night" (unless only times past midnight are considered night)
> 7
in both of these solutions means that the condition will only be true for 8:00:00 and later- the condition in the OP would render the condition to be true from
8:10
till midnight every minute except the first few minutes from the full hour to 10 minutes past - the
Time.minute() == 0
condition relies on actually sleeping for at least one minute after the check, so any change inside the conditional block that does away with the sleep may break the logic of the condition potentially causing confusion. - in case the sleep wasn't there the equality check for mintues would cause the condition to be true one minute long
If you want to make a range check for timestamps, I'd always go with Time.local() % 86400
which gives you one number for the full time part of the UNIX epoch date/time (hh:mm:ss).
With that number you won't be confronted with exponental complexity for your range checks for extra fields.
e.g.
// simple check for only hours (do stuff 7am till just before 8pm)
if (Time.hour() >= 7 && Time.hour() < 20)
// quickly gets messy with minutes added (do stuff from 7:10am till just before 8:10pm)
if ((Time.hour() >= 7 && Time.minute() >= 10 || Time.hour() > 7) && (Time.hour() < 8 || Time.hour() <= 8 && Time.minute() < 10))
And then you haven't had the "execute only once per minute" guard in place.
With one and only one number for the full timestamp things look a bit easier
const int startTime = 7*3600 + 10*60 + 0*1; // 7:10:00 - 3600 seconds to the hour 60 to the minute
const int stopTime = 20*3600 + 10*60 + 0*1;
int oneShotGuard = -1;
...
int currentSecond = Time.local() % 86400; // 86400 seconds to the day
if (startTime < currentSecond && currentSecond < stopTime && currentSecond != oneShotGuard) {
oneShotGuard = currentSecond;
// do whatever without breaking the condition
}
To change the timeframe you just alter the two constants and are done and the condition is (almost) independent of the active block - only the first line has to be considered in connection, but since it follows immediately and works on a variable that's and intrinsic part of the condition the connection is obvious (which isn't the case with the implicit impact of a System.sleep()
call).
Granted, the check to repeat things once an hour isn't implemented there, but can be added much easier to the latter solution than to the former - in a similar fashion as the oneShotGuard
(e.g. oneShotGuard = Time.hour()
to only act once per hour - usually on the full hour since that's the earilest time the number changes ).