1. Overview
Comparing time values in a shell environment can be useful when making decisions based on time or when writing scripts containing time-dependent logic. For example, a script can be designed to trigger specific events or show different output depending on the time of day.
In this tutorial, we’ll explore how to compare time in Bash.
2. Sample Task
Let’s suppose we wish to write a Bash script check_time.sh that outputs a different message depending on the time of day:
- if the current time is between 9:00 AM and 5:00 PM, we’d like the script to print the message Current time is within working hours interval
- otherwise, the script should print Current time is outside working hours interval
Of course, we can get the current date and time using the date command:
$ date
Thu 17 Aug 2023 04:41:28 PM EEST
Therefore, in this case, the time is 4:41 PM, and the script should indicate that the current time is within the working hours interval.
Let’s explore how we can compare time in a shell script to accomplish this task.
3. Using Unix Epoch Time
One way to compare two time values is to first transform each into the number of seconds since the Unix epoch, and then use the test operator to compare the numeric values.
We can show any date in terms of Unix epoch time via the %s option when using date:
$ date +'%s'
1692279750
To specify a time of 9:00 AM today, we can use the -d option:
$ date -d '9:00' +'%s'
1692252000
Likewise, to specify a time of 5:00 PM, we can use the -d option with either the 24-hour clock notation or AM/PM notation:
$ date -d '5:00 PM' +'%s'
1692280800
$ date -d '17:00' +'%s'
1692280800
We’re now ready to implement the check_time.sh script to output different messages based on the time of day. Let’s see the result with cat:
$ cat check_time.sh
#!/usr/bin/env bash
current_time="$(date +'%s')"
lower_bound="$(date -d '9:00' +'%s')"
upper_bound="$(date -d '17:00' +'%s')"
if [ "${current_time}" -ge "${lower_bound}" -a "${current_time}" -lt "${upper_bound}" ]; then
echo 'Current time is within working hours interval'
else
echo 'Current time is outside working hours interval'
fi
After setting the shebang directive on the first line, we use command substitution to save the current Unix time in seconds within a variable named current_time. Similarly, we save the Unix time values at 9:00 AM and 5:00 PM in the lower_bound and upper_bound variables, respectively.
Subsequently, we can perform an arithmetic comparison of timestamps using the test operator indicated by the square brackets ([]) notation:
- -ge within [] represents the greater than or equal operator
- -lt represents the less than operator
- -a indicates a logical AND operation between two statements
Therefore, if the value of the current_time variable is greater than or equal to the value of the lower_bound variable and less than that of the upper_bound variable, we print the message Current time is within working hours interval. Otherwise, we print the message Current time is outside working hours interval.
Let’s grant the script execute permissions via chmod:
$ chmod +x check_time.sh
Finally, let’s run the script after checking the current date and time:
$ date
Thu 17 Aug 2023 04:43:15 PM EEST
$ ./check_time.sh
Current time is within working hours interval
We see that the current time, 4:43 PM, is indeed within the working hours interval.
4. Using Hours and Minutes
Another approach to accomplish the task is by comparing time values explicitly based on the hour and minute values.
In particular, we can use the %k option with the date command to obtain the hour value in the 24-hour clock notation. Also, for the minute value, we can use the %M option.
Therefore, we can concatenate both hour and minute via %k%M:
$ date +'%k%M'
1643
This indicates that the current time is 16:43.
Now, we can modify how we define the three variables in the check_time.sh script:
$ cat check_time.sh
#!/usr/bin/env bash
current_time="$(date +'%k%M')"
lower_bound='900'
upper_bound='1700'
if [ "${current_time}" -ge "${lower_bound}" -a "${current_time}" -lt "${upper_bound}" ]; then
echo 'Current time is within working hours interval'
else
echo 'Current time is outside working hours interval'
fi
The current_time variable is now based on the hour and minute values. Also, the lower_bound variable is set to 900 representing 9:00, and the upper_bound variable is set to 1700 representing 17:00, both in the 24-hour clock notation. The rest of the script remains intact.
Let’s check the current date and time and run the script:
$ date
Thu 17 Aug 2023 04:44:16 PM EEST
$ ./check_time.sh
Current time is within working hours interval
We obtain the same result as before since the current time, 4:44 PM, falls within the working hours interval of 9:00 to 17:00.
5. Using awk
Alternatively, we can use GNU awk to accomplish our task.
In particular, *we use awk‘s built-in strftime() function to extract the hour and minute values*. The function accepts %k%M as input, matching the options used with the date command earlier.
We first modify our script to use awk:
$ cat check_time.sh
#!/usr/bin/awk -f
BEGIN {
current_time = strftime("%k%M")
if (current_time >= 900 && current_time < 1700) {
print "Current time is within working hours interval"
} else {
print "Current time is outside working hours interval"
}
}
In this case, we’re only using a BEGIN clause. Within it, we define the current_time variable using the strftime function. The variable’s value gets converted numerically when compared against other numeric values:
- if the value of the current_time variable is greater than or equal to 900 and is less than 1700, we print the message Current time is within working hours interval
- otherwise, we print the message Current time is outside working hours interval
Next, we run the script after checking the current date and time:
$ date
Thu 17 Aug 2023 04:45:57 PM EEST
$ ./check_time.sh
Current time is within working hours interval
We see that we achieve the same result as before.
6. Conclusion
In this article, we explored how to compare time in Bash for designing time-dependent logic in scripts. In particular, the methods either converted the timestamps into seconds since the Unix epoch or extracted the hour and minute values before conducting a comparison using the test operator. Additionally, we saw how we can use awk and its built-in strftime() function to achieve the same results.