Working hours logic

Hi,
I am up to make a project where certain things will be done but in a specific frame of time every day.
Firstly, it was ok to have only hours time frame:


if (hr >= startHour && hr < stopHour){
    do something
    }else{
      don't do something
      }

So if I have startHour = 8 and stopHour = 12, the thing will be done from 8 up to 12h. This is fine.

Now, I have to add minutes. Tried something like this:

if (hr >= startHour  && hr < stopHour){
    if(min >= startMin   && min < stopMin){
     do something
    }else{
      don't do something
      }
    }else{
      don't do something
      }

This works if the startMin is less than the stopMin. Say from 8:10 to 12:20, but it will not work if it is from 8:20 up to 12:10.

Anyone of you have messed with this logic? Any help would be nice.

Use time not in hours and minutes, but in minutes from midnight. That is, 4 hours is 240 minutes, and 11 hours 10 minutes is 670 minutes.

So, your condition will be:

@who_took_my_nick you might find it slightly easier to measure time as hours * 100 + minutes. Then you can write 810 for 08:10 and 1220 for 12:20. It saves you a little mental arithmetic!

PS. don't write 0810 for 08:10 because in C, any number beginning with a zero is in octal, not decimal

2 Likes

The best solutions are always simple.

I will try and let you know. Thank you.

OK.
It works great.
Agree with @PaulRB. It is better to multiply with 100. The head hurts less.

The only issue could be if the start time is, say 22:25 and the stop time is 02:10, or so.

Edit:

I use int as a data type, so there is no leading 0.

Do you think that int can't be octal?

1 Like

Int can not be 01, only 1.

Am I wrong?

Why not?

Test this code:

int x = 0677;

void setup() {
Serial.begin(9600);
Serial.print(" x = ");
Serial.println(x);
}

void loop() { }

Interesting, what will be the output? :slight_smile:

All of this are perfectly legal assignments for int type:

int a = 0b00000001;   // binary
int b = 0777;        // octal
int c = 0x5657;     //hex
int d = 1234;      //decimal
1 Like

You suggest to strip the eventual leading zero?

rather than using custom logic for each case consider a data driven approach using a table to define the conditions for multiple actions. see Creation of OS Scheduler

1 Like

In your code definitely yes.

In general, it will be better if you learn a various numeric representations as octal, hex... and understand them.

What should be the solution to bypass the 24 hours format?
Say, it starts at 22:00 and ends at 2:00?

post #3
works nice. It should be changed a little bit.

Using a RTC with a full timestamp (seconds from 01 Jan 1970) allows you to control an any type of interval.

It might hurt your brain, but take a look at:

and figure out if your time library has an 'epoch' style variable.
I'd try to help more, but you haven't posted a complete code, just snippets, so I have no idea which library you're using. Too bad.

1 Like

Actually, I will just check if the end time > of start time and do things. I will post here what I came up.

It's the same only using the or operator || , like:

// somewhere 

const int startTime = 2200;
const int stopTime = 200;



// later on

  int timeNow = now.hour() * 100 + now.minute();

  if (timeNow >= startTime || timeNow < stopTime)
    doSomething();

You coukd figure out which to use, && or || with a bit more logic at each time testing section, or ahead of, um, time.

a7

1 Like

Hi @who_took_my_nick ,

you can handle the three different possibilities per day

  • Start time before stop time
  • Start time after stop time and
  • Start time equal stop time

as follows:

/*
  Forum: https://forum.arduino.cc/t/working-hours-logic/1228983/11
  Wowki: https://wokwi.com/projects/390883908441457665
  
*/

int startTime;
int stopTime;


void setup() {
  Serial.begin(115200);
  calcStartStopTime(8,10,12,0);
  checkTime(7,0);
  checkTime(10,12);
  checkTime(13,0);
  calcStartStopTime(12,0,8,10);
  checkTime(7,0);
  checkTime(10,12);
  checkTime(13,0);

  calcStartStopTime(12,0,12,0);
  checkTime(7,0);

}

void loop() {
}

void calcStartStopTime( int startH, int startM, int stopH, int stopM){
  startTime = startH*60+startM;
  stopTime  = stopH*60 +stopM;
  Serial.print("\nStart Time : ");
  printTime(startH, startM);
  Serial.print("  Stop Time : ");
  printTime(stopH, stopM);
  Serial.println();
}

void checkTime(int hour, int minute) {
  boolean isWorkingTime = false;
  unsigned long timeInMinutes = hour * 60 + minute;
  printTime(hour, minute);
  byte mode;
  if (stopTime < startTime) {
    mode = 0;  // start  after stop
  } else {
    mode = 1;  // stop after start
  }
  if (startTime == stopTime) {
    mode = 2; // start and stop at the same time 
  }
  switch (mode) {
    case 0:  // stop before start
      isWorkingTime = !(timeInMinutes >= stopTime && timeInMinutes < startTime );
      break;
    case 1:  // Deactivation later
      isWorkingTime = (timeInMinutes >= startTime && timeInMinutes < stopTime );
      break;
    case 2:  // At the same time ... ?!! 
      Serial.println("All day working OR lazy?");
      break;
  }
  if (mode != 2 ){
    Serial.println(isWorkingTime ? "Working Time" : "Free Time");
  }
}

void printTime(int h, int m){
  if (h < 10) {
    Serial.print('0');
  }
  Serial.print(h);
  Serial.print(":");
  if (m < 10) {
    Serial.print('0');
  }
  Serial.print(m);
  Serial.print('\t');

}

Feel free to check out this example sketch on Wokwi: https://wokwi.com/projects/390883908441457665

The solution is to compare startTime and stopTime to find out which of the three cases is relevant.

If stopTime is larger than startTime Working Time is the interval between startTime and stopTime.

If stopTime is less than startTime the sketch checks for the interval between stopTime and startTime (which is "Free Time") and inverts the result (Working Time = !Free Time).

what does something mean?

  • something needs to be executed each iteration of loop()?
  • something needs to be turned on at the start of the period and turned of at the end of the period?

for the first case, can something be enabled at the start of the period and if enabled, dis-abled at the end of the period? does the system identify a period or two separate events that happen to control, start/stop the same something

the 2nd case could also be handled by recognizing events at specific times.

so a something could be enabled at 23:50 and disabled at 0:10

1 Like
uint16_t time = now.hour()*100 + now.minute();
if (time >= 2200 or time < 200){
    // do something
    }else{
     // don't do something
    }

The entire computing world has been using epoch-based time in some form or another since the 1970s. Why invent a new format?