# Possible to condense this if statement?

I have this if statement:

``````if (now.hour() == 5 && now.minute() == 10 && now.second() == 0 && now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7){
``````

Is there a way to condense that for the purposes of saving on some bytes?

Ultimately trying to say "At 5:10 every weekday do X"

• If this is using too much space then it's not the condition responsible, it's `now`. – Ignacio Vazquez-Abrams May 21 '16 at 1:31
• Well, I was fine (just barely under) until I added the `&& now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7`. – Shpigford May 21 '16 at 1:33
• In most libraries `now.dayOfTheWeek()` will actually calculate the day of the week, where at the other functions just load their value straight from the RTC chip. Calculating the day of the week is quite a bit of work. That would explain the jump in code size. The weird thing is that the RTC chip will actually keep track of the day of the week. – Gerben May 21 '16 at 9:32

## 2 Answers

The following saves a couple of program bytes (but no RAM) when `now` is a structure with a byte called `DayofWeek`:

`````` if ((byte)(now.DayofWeek+249)>250) ...
-vs-
if ((now.DayofWeek != 1 && now.DayofWeek != 7)) ...
``````

It might save slightly more than that in your case, where `now.dayOfTheWeek()` appears to be a function reference. This technique will work if function `now.dayOfTheWeek()` returns a `byte`, that is, an `unsigned char`. The technique depends on value 7+249 overflowing to zero in byte arithmetic when truncated to a byte, because 7+249 is 0 modulo 256.

The cast to `byte` [or `uint8_t`] of `now.DayofWeek+249` is needed because of `int` promotion as Edgar Bonet pointed out.

• This does not work. You have to cast the sum to `uint8_t`. Otherwise, per the rules of integral promotion, everything in the expression is evaluated as 16-bit signed ints. – Edgar Bonet May 21 '16 at 11:56
• @EdgarBonet, it does work. Specifically, it gives correct results for `now.DayofWeek` values from 1 to 7. Note, `now.DayofWeek` is declared as a byte (which is equivalent to uint8_t except for being easier to pronounce) so `byte`, not `int`, arithmetic is used. – James Waldby - jwpat7 May 21 '16 at 23:31
• No, it doesn't, and you obviously did not try. If `DayofWeek` is 7, then `DayofWeek+249` is 256, and since 256>250, the test succeeds, while it shouldn't. Note: there is no such thing as “byte arithmetic” in C: the operation is done on ints. C.f. for example this CERT article on integer conversion rules and, more specifically, the section titled “Integer Promotions”. – Edgar Bonet May 22 '16 at 7:38
• @EdgarBonet, unfortunately my test printed out the result of assigning `now.DayofWeek+249` to a byte – hence the value I expected – rather than the result of the comparison :( , See edit – James Waldby - jwpat7 May 22 '16 at 16:21

Yes. The method now() Returns the current time as seconds since Jan 1 1970. Simply keep tract of all your time this way and you only need to test this one value.

The Arduino is not a good source of time over long periods. Consider using an RTC (Real Time Clock) chip. This Arduino page links to this page which talks about an RTC. (I will leave it up to you to research any compatibility issues.)

Many RTCs contain a register set specifically designed to handle tasks such as you outlined above. For example, setting alarms off on weekdays only or on specific days of the month.

If absolute time is not important in your application I would try the following code outline. Each test only has 2 operands:

``````// Turn on Arduino on Monday at the time task is to be performed.  Task
// should be performed at that time on Monday, Tuesday, ... Friday.
// Nothing should happen on Saturday & Sunday.  Then cycle repeats.

// Set time to zero.

// Count through days (0, 1, 2, ...).

// Wait each day until number-of-seconds is greater then seconds-in-a-day
// times the day number.

// If day number is 4 or less do activity.  Else skip activity.

// If day number is more than 6 set the day counter to 0 and set the time
// to zero.
``````

If you want to start the Arduino at arbitrary times, set the initial Arduino clock value to the number of seconds from the time the activity would have been performed on Monday and initialize the day counter to the appropriate value. For example if you started the Arduino on Tuesday 23 hours after the time the activity should have happened on Monday set the Arduino clock to 23 * 60 * 60 seconds and initialize the day counter to 2. Of course you can calculate the initial day counter value using = initial_number_of_seconds / 60 * 60 * 24.

• I'm trying to get it to be `true` at a specific time every weekday, so I'm not sure how what you've said applies here. – Shpigford May 21 '16 at 1:36
• Answer has been changed. Consider an RTC. Most RTCs contain a hardware solution for your situation. If Arduino time drift is tolerable, use the code outline which only uses seconds in a week to drive events. – st2000 May 21 '16 at 14:47