How to check if the current time is between 23:00 and 06:30

If all you need is to check if HH:MM is between 23:00 and 06:30, then don't use Unix timestamps. Just check the HH:MM values directly:

fireup()
{  
  while :; do
   currenttime=$(date +%H:%M)
   if [[ "$currenttime" > "23:00" ]] || [[ "$currenttime" < "06:30" ]]; then
     do_something
   else
     do_something_else
   fi
   test "$?" -gt 128 && break
  done &
}

Notes:

  • Time in HH:MM will be in lexicographic order, so you can directly compare them as strings.
  • Avoid using -a or -o in [ ], use || and && instead.
  • Since this is bash, prefer [[ ]] over [ ], it makes life easier.

If you want to be more explicit about the times you want to match, you could use a case statement. Here's a 24-hour loop with a case statement inside that indicates whether the current time matches your range:

for hh in {00..23}
do
  for mm in {00..59}
  do
    case $hh:$mm in
        (23:*)        echo YES $hh:$mm;;
        (0[012345]:*) echo YES $hh:$mm;;
        (06:[012]*)   echo YES $hh:$mm;;
        (*)           echo  NO $hh:$mm;;
    esac
  done
done

To use it in your script, just replace the variables with a call to date:

case $(date +%H:%M) in
    (23:*)        echo YES;;
    (0[012345]:*) echo YES;;
    (06:[012]*)   echo YES;;
    (*)           echo NO;;
esac

You might consider being friendlier to your CPU and computing the amount of time between (now) and the next start time, and sleep for that amount of time.


You can convert the time to seconds since the start of "this" day and then check that the seconds value is either greater than 23*60*60 (82800) or lower than 6*60*60+30*60 (23400).

To get seconds since the start of "this" day you can do:

secsSinceMidnight=$(( $(date +%s) - $(date -d '00:00:00' +%s) ))

And the test would be:

[[ $secsSinceMidnight -lt 23400 || $secsSinceMidnight -gt 82800 ]] && echo YES

Tags:

Scripting

Date