#!/bin/bash get_fraction() { st=$(date --date "$1" +%s) en=$(date --date "$2" +%s) now=$(date +%s) total=$(( en - st )) already_done=$(( now - st )) passed=$(echo "$already_done * 100 / $total" | bc -l) onesec=$(echo "1/$total" | bc -l) } determine_auto_precision() { mapfile -t digits < <(echo "$onesec" | cut -d'.' -f2 | grep -o .) for i in "${!digits[@]}"; do if [[ ${digits[i]} -ne 0 ]]; then echo $(( i + 1 )) return fi done echo 0 } main() { start_time=$(date +'%Y-%m-%d %H:%M:%S' -d "January 1") end_time=$(date +'%Y-%m-%d %H:%M:%S' -d "January 1 next year") precision="auto" format="%\n" while [[ $# -gt 0 ]]; do case $1 in -h|--help) echo "Usage: percentages [-s START] [-e END] [-p PRECISION] [-f FORMAT]" echo "" echo "Print how far through a time interval you are as a percentage." echo "Defaults to the current calendar year." echo "" echo "Options:" echo " -s, --start START Start datetime (default: Jan 1 this year)" echo " -e, --end END End datetime (default: Jan 1 next year)" echo " -p, --precision DIGITS Decimal places (default: auto)" echo " -f, --format SUFFIX String appended after the number (default: '%\n')" echo " -h, --help Show this help message" exit 0 ;; -s|--start) start_time=$2 shift 2 ;; -e|--end) end_time=$2 shift 2 ;; -p|--precision) precision=$2 shift 2 ;; -f|--format) format=$2 shift 2 ;; *) shift ;; esac done get_fraction "$start_time" "$end_time" [[ $precision == "auto" ]] && precision=$(determine_auto_precision) string=$(printf "%.${precision}f\n" $passed) echo -e -n "${string}${format}" } main "$@"