1

basically I need a time switch in C. I get the current date and time using strftime. So at the end I have the information as a string.

For the time switch I only need to compare hours and minutes. So in pseudocode e.g.:

static bool isSwitchedOn = false;
if(timeOfDay>timeToSwitchOn && !isSwitchedOn) {
   switchOn(); 
   isSwitchedOn = true;
} 
else if(timeOfDay>=timeToSwitchOf && isSwitchedOn) {
   switchOff(); 
   isSwitchedOn = false;
} 

One solution would be to use atoi to convert all the times to int and then compare hours and minutes separate.

I saw that I could maybe use difftime, but this requires also a date and I would like not to use dates at all. So and because I already have the times this question is not a duplicate of How do I measure time in C?

EDIT: Sorry, I was not clear enough. I do not have date information available for the time I compare the current time with. It is more like on every day at time 20:33 turn on and 20:55 turn off.

Is there a better solution?

Thanks

Roland
  • 131
  • 7
  • Possible duplicate of [How do I measure time in C?](https://stackoverflow.com/questions/3557221/how-do-i-measure-time-in-c) – bolov Jul 29 '19 at 13:08
  • 1
    if you used `strftime` doesn't it mean you had the time in a structure? Can't you just use those values? – Federico klez Culloca Jul 29 '19 at 13:15
  • How can I use time() if I have to compare the current time with e.g. the time "20:33"? – Roland Jul 29 '19 at 13:17
  • The value from `time()` modulo `(24 * 60 * 60)` (aka 86400) gives you the number of seconds since the start of the day (midnight UTC) on POSIX machines. The POSIX time system does not track leap seconds. If you don't live in the UTC time zone, you'll need to compensate for your time zone offset from UTC — which is where life starts to get trickier. – Jonathan Leffler Jul 29 '19 at 14:52

2 Answers2

1

strftime() is based on a value of struct tm.
Use that value directly for your comparisons, rather than the string.

int timeToSwitchOn = 2033; // switch on a little after 8pm
int timeToSwitchOff = 2055; // switch off just before 9pm
// strftime(..., &tm);
if (tm.tm_hour*100 + tm.tm_min > timeToSwitchOn && !isSwitchedOn) {
    switchOn(); 
    isSwitchedOn = true;
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • 1
    @chqrlie: OP said: "For the time switch I only need to compare hours and minutes" – pmg Jul 29 '19 at 13:19
  • 1
    OK. Yet I would use defensive programming and compare to both `timeToSwitchOn` and `timeToSwitchOff` just in case the test is invoked at a random time, for example during a power on sequence. – chqrlie Jul 29 '19 at 13:23
0

It is easy to compute a 24 hour based number of minutes from the tm structure instead of converting it to a string with strftime():

timeOfDay = t.tm_hour * 60 + t.tm_min;

Yet your method has a flaw: if the system is started after the timeToSwitchOf and timeToSwitchOn < timeToSwitchOf, the switch would be turned on incorrectly. An error like this might explain why the street lights are sometimes lit in broad day light.

Here is a modified the test:

struct tm t;   // this is populated for the current time
...
static bool isSwitchedOn = false;
int timeOfDay = t.tm_hour * 60 * t.tm_min;

if ((timeToSwitchOn < timeToSwitchOff && (timeOfDay >= timeToSwitchOn && timeOfDay < timeToSwitchOff))
||  (timeToSwitchOn > timeToSwitchOff && (timeOfDay >= timeToSwitchOn || timeOfDay < timeToSwitchOff)) {
        if (!isSwitchedOn) {
            switchOn(); 
            isSwitchedOn = true;
        }
    } else {
        if (isSwitchedOn) {
            switchOff(); 
            isSwitchedOn = false;
        }
    }
}

Note that the special case timeToSwitchOn == timeToSwitchOff here means always off. If you want the system to be always on, set timeToSwitchOn = 0 and timeToSwitchOff = 24 * 60.

chqrlie
  • 131,814
  • 10
  • 121
  • 189