Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Time Calculator

Quickly calculate when it's time to leave or when something will be over.

Because the calculation of clock times is a bit cumbersome. At least if it is not carried out regularly.

Examples

Here, I want to be somewhere at 19:30 and have three things to do that take 20, 10 and 15 minutes:

$ ./timecalc.sh 19:30 -20 -10 -15
19:30
19:10 -00:20
19:00 -00:10
18:45 -00:15
18:45

So I have to start at 18:45.

Here, I want to now when I will be home after a movie that takes 128 minutes and starts at 20:00:

$ ./timecalc.sh 20 128 20
20:00
22:08 02:08
22:28 00:20
22:28
#!/usr/bin/env bash
# Print clock time of given timestamp
#
# @param 1 - timestamp
clocktime() {
if date --version &>/dev/null
then
# GNU
date -d "@$*" +%H:%M
else
# BSD
date -j -f '%s' "$@" +%H:%M
fi
}
# Print timestamp of given date and time
#
# @param ... - date and time in format 'YYYY-MM-DD HH:MM:SS'
timestamp() {
if date --version &>/dev/null
then
# GNU
date -d "$@" +%s
else
# BSD
date -j -f '%Y-%m-%d %H:%M:%S' "$@" +%s
fi
}
# Print timestamp of given time of day
#
# @param 1 - time in HH[:MM] format
hours_to_timestamp() {
local TIME=$1
[[ $TIME == *:* ]] || TIME=$TIME':00'
timestamp "$(date +%Y-%m-%d) $TIME:00"
}
# Convert duration from hours and minutes into seconds
#
# @param 1 - duration in [HH:]MM format
minutes_to_seconds() {
local D=$1
[[ $D == *:* ]] && {
local SIGN=
[[ $D == -* ]] && SIGN=-
D=$(($SIGN${D##*:} + ${D%%:*} * 60))
}
echo $((D * 60))
}
# Expand duration to HH:MM format
#
# @param 1 - duration in [HH:]MM format
minutes_to_clocktime() {
local T=${1#-}
[[ $T == *:* ]] || T=$(printf '%02d:%02d' "$((T / 60))" "$((T % 60))")
local SIGN=
[[ $1 == -* ]] && SIGN=-
echo "$SIGN$T"
}
# Print time ruler
#
# @param 1 - target time in HH[:MM] format
# @param ... - time ranges in [HH:]MM format
ruler() {
local TIME
TIME=$(hours_to_timestamp "$1")
clocktime "$TIME"
shift
for T
do
((TIME += $(minutes_to_seconds "$T")))
echo "$(clocktime "$TIME")" "$(minutes_to_clocktime "$T")"
done
clocktime "$TIME"
}
if [ "${BASH_SOURCE[0]}" == "$0" ]
then
if (($# < 2))
then
echo "usage: ${0##*/} HH[:MM] [HH:]MM..."
else
ruler "$@"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.