Skip to content

Instantly share code, notes, and snippets.

@christofluethi
Last active January 4, 2024 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christofluethi/4c44130b23de3584800bd7df6a239e34 to your computer and use it in GitHub Desktop.
Save christofluethi/4c44130b23de3584800bd7df6a239e34 to your computer and use it in GitHub Desktop.
Work time calculator
#!/bin/zsh
if [ "$1" = "--help" -o "$1" = "-h" -o $# -gt 4 ]; then
echo "Simple calculator for same-day office hour calculation\n"
echo "Usage: $0 [-h] [start] [end] [break] [output]\n"
echo " start: Start of working or '0' to use the system boot time. Format hh:mm"
echo " end: End of working or '0' to use the current time. Format hh:mm"
echo " break: Minutes to be subtracted from work time. AKA lunch break, etc."
echo " output: Use 'short' for a one-line output.\n\n"
echo "Examples: "
echo " Use explicit times: "
echo " $0 8:05 17:20 45\n"
echo " Use system boot and current time:"
echo " $0 0 0 60\n"
echo " If you restarted your system during the day specify your start time:"
echo " $0 8:20 0 60\n"
echo " Predict your office hours at 5pm:"
echo " $0 0 17:00 30\n\n"
echo "Sample output:"
echo " $0 8:00 17:00 45"
echo " Work Start 08:00"
echo " Work End 17:00"
echo " Break 45 min"
echo " Worktime 08h 15m 00s"
echo " WT Decimal 8.25h\n\n"
echo " $0 8:00 17:00 45 short"
echo " 2024-01-04 14:08:20 08:00 17:00 45 08h 15m 00s 8.25h"
exit 1
fi
typeset -gA worktime=()
function calculate() {
local INARG=$1
local OUTARG=$2
local BREAK=$3
local SHORT=$4
if [ "$INARG" = "0" ] || [ -z "$INARG" ]; then
INARG=`who -b | awk '{ print $4 }'`
fi
local IN=$(date +'%H:%M' -d $INARG)
if [ -z "$OUTARG" ] || [ "$OUTARG" = "-" ] || [ "$OUTARG" = "0" ]; then
OUTARG=$(date +'%H:%M')
fi
local OUT=$(date +'%H:%M' -d $OUTARG)
if [ -z "$BREAK" ]; then
local BREAK=0
fi
if [ -z "$SHORT" ] || [ "$SHORT" != "short" ]; then
SHORT="normal"
fi
local TS_START="$(date +'%m-%d-%Y')@:$IN:00"
local TS_END="$(date +'%m-%d-%Y')@:$OUT:00"
local seconds=$(( ($(date2sec "$TS_END") - $(date2sec "$TS_START")) ))
bseconds=$(( BREAK * 60 ))
local workseconds=$(expr $seconds - $bseconds)
seconds2array $workseconds
if [ "$SHORT" = "normal" ]; then
printf "%-15s %-11s\n" "Work Start" $IN
printf "%-15s %-11s\n" "Work End" $OUT
printf "%-15s %-15s\n" "Break" "$BREAK min"
printf "%-15s %-s" "Worktime" ""
else
printf "%s\t%s\t%s\t%s\t" "`date +'%F %H:%M:%S'`" $IN $OUT $BREAK
fi
(( ${worktime[DAY]} > 0 )) && printf '%02dd ' ${worktime[DAY]}
(( ${worktime[HOUR]} > 0 )) && printf '%02dh ' ${worktime[HOUR]}
(( ${worktime[MIN]} > 0 )) && printf '%02dm ' ${worktime[MIN]}
(( ${worktime[DAY]} > 0 || ${worktime[HOUR]} > 0 || ${worktime[MIN]} > 0 ))
printf '%02ds' ${worktime[SEC]}
if [ "$SHORT" = "normal" ]; then
printf "\n%-15s %s" "WT Decimal"
else
printf "\t"
fi
printf '%.2fh\n' ${worktime[DEC]}
}
function date2sec {
date -d "$(sed 's|-|/|g; s|@| |; s|:| |' <<<"$*")" +%s;
}
function seconds2array {
local T=$1
local D=$((T/60/60/24))
local H=$((T/60/60%24))
local M=$((T/60%60))
local S=$((T%60))
local DEC=$(( H + (M/60.0) ))
worktime[DAY]=$D
worktime[HOUR]=$H
worktime[MIN]=$M
worktime[SEC]=$S
worktime[DEC]=$DEC
}
calculate "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment