Three codes to run timed code after sleep mode

Hello,
I would like to activate a motor for 3 minutes a day.
Since the system is battery powered I am going to use the RTC DS3231 to wake up the PRO MINI at a specific time every day in order to run a water pump for 3 minutes.

I came out with three different solutions (and I imagine the good one is not among them):
To keep it short I did not paste the setup.
I am using the following libraries:

#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>

Solution 1: Use of millis()

void loop() {
  delay(100) //delay 
  unsigned long currentTime = millis();
  if(currentTime - previousTime > interval){
  Going_To_Sleep(); //put Arduino on sleep mode
  }
  WaterPump();
}
void Going_To_Sleep(){
    sleep_enable();//Enabling sleep mode
    attachInterrupt(0, WakeUp, FALLING); //0 for D2 pin
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting up the sleep mode
    sleep_cpu();//activating sleep mode
  }

void WakeUp(){
   sleep_disable();//Disable sleep mode
   detachInterrupt(0); //Removes the interrupt from pin 2;
   previousTime = millis();
}

void WaterPump(){
  //code for the water pump

}

Practically, after the interrupt, the variable previousTime will be changed with the current time and the the function WaterPump is called until the interval is passed.
Advantages: simple, just combination of standard code
Disadvantages: the variable of time is declared as unsigned long and it can record up to 50ish days

Solution 2: Use of the alarm as latching switch

  delay(100) //delay 
  unsigned long currentTime = millis();
  if(SwitchState == 1){
  time_t t; //create a temporary time variable so we can set the time and read the time from the RTC
  t=RTC.get();//Gets the current time of the RTC
  RTC.setAlarm(ALM1_MATCH_HOURS , 19, 30, 0, 0);// Setting alarm 1 to go off at 7:30pm every day
  RTC.alarm(ALARM_1);
  // enable interrupt output for Alarm 1
  RTC.alarmInterrupt(ALARM_1, true);
  Going_To_Sleep(); //put Arduino on sleep mode
  } 
  WaterPump();

void Going_To_Sleep(){
    SwitchState == 1
    sleep_enable();//Enabling sleep mode
    attachInterrupt(0, WakeUp, FALLING); //0 for D2 pin
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting up the sleep mode
    sleep_cpu();//activating sleep mode
  }

void WakeUp(){
   sleep_disable();//Disable sleep mode
   detachInterrupt(0); //Removes the interrupt from pin 2;
   SwitchState =0 ;
     time_t t; //create a temporary time variable so we can set the time and read the time from the RTC
    t=RTC.get();//Gets the current time of the RTC
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+5, 0, 0);// Setting alarm 1 to go off 5 minutes from now
    RTC.alarm(ALARM_1);
    // enable interrupt output for Alarm 1
    RTC.alarmInterrupt(ALARM_1, true);
    attachInterrupt(0, Going_To_Sleep, FALLING); //0 for D2 pin

}

void WaterPump(){
  //code for the water pump

}

Practically the interrupt can call two functions (GoingToSleep or Wakeup) according to the value of the variable SwitchCase
Advantages: use of the interrupts and good if interval is quite long
Disadvantages: cumbersome code

Solution 3: Get time from RTC and use instead of millis()

void loop() {
  delay(100) //delay 
  time_t t; //create a temporary time variable so we can set the time and read the time from the RTC
    t=RTC.get();//Gets the current time of the RTC
  if(t - previousTime > interval){
  Going_To_Sleep(); //put Arduino on sleep mode
  }
  WaterPump();
}
void Going_To_Sleep(){
    sleep_enable();//Enabling sleep mode
    attachInterrupt(0, WakeUp, FALLING); //0 for D2 pin
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting up the sleep mode
    sleep_cpu();//activating sleep mode
  }

void WakeUp(){
   sleep_disable();//Disable sleep mode
   detachInterrupt(0); //Removes the interrupt from pin 2;
   previousTime = RTC.get();
}

void WaterPump(){
  //code for the water pump

}

Advantages: avoid the problem of Solution 1, it can be run indefinitely
Disadvantages: not sure about calculations with variable time

Any idea or comments? Can every solution work? Is there any better? Thanks

For solution #1, you have a disadvantage of millis() rolling over ~50 days but that is not a disadvantage. If you code it properly (like you did), having millis() rollover does not impact your code. That is the beauty of unsigned math.

(all unsigned)
Say currentTime = 1;
Say prevTime = 4294967295; // highest value for unsigned long

then currentTime - prevTime = 1 - 4294967295 == 2!

The math still works.

blh64:
For solution #1, you have a disadvantage of millis() rolling over ~50 days but that is not a disadvantage. If you code it properly (like you did), having millis() rollover does not impact your code. That is the beauty of unsigned math.

(all unsigned)
Say currentTime = 1;
Say prevTime = 4294967295; // highest value for unsigned long

then currentTime - prevTime = 1 - 4294967295 == 2!

The math still works.

Thanks, I did not know about this property.
I thought unsigned was like the absolute value. I think I ll go with solution 1. Cheers

Yes, #1 is clean, simple and readable.
Within the info you’ve given, it’s the way to go.