Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Last active July 23, 2024 19:17
Show Gist options
  • Save markusfisch/8c54cda46a2cb6a47c22e71cb0fe4403 to your computer and use it in GitHub Desktop.
Save markusfisch/8c54cda46a2cb6a47c22e71cb0fe4403 to your computer and use it in GitHub Desktop.

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 know 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