+++ /dev/null
-#!/bin/bash
-
-# Desc: Template to indicate time duration in ISO-8601 format
-
-yell() { echo "$0: $*" >&2; } # Yell, Die, Try Three-Fingered Claw technique; # Ref/Attrib: https://stackoverflow.com/a/25515370
-die() { yell "$*"; exit 111; }
-try() { "$@" || die "cannot $*"; }
-timeDuration(){
- # Desc: Given seconds, output ISO-8601 duration string
- # Ref/Attrib: ISO-8601:2004(E), §4.4.4.2 Representations of time intervals by duration and context information
- # Note: "1 month" ("P1M") is assumed to be "30 days" (see ISO-8601:2004(E), §2.2.1.2)
- # Usage: timeDuration [1:seconds] ([2:precision])
- # Version: 1.0.5
- # Input: arg1: seconds as base 10 integer >= 0 (ex: 3601)
- # arg2: precision level (optional; default=2)
- # Output: stdout: ISO-8601 duration string (ex: "P1H1S", "P2Y10M15DT10H30M20S")
- # exit code 0: success
- # exit code 1: error_input
- # exit code 2: error_unknown
- # Example: 'timeDuration 111111 3' yields 'P1DT6H51M'
- # Depends: date 8, bash 5, yell,
- local argSeconds argPrecision precision returnState remainder
- local fullYears fullMonths fullDays fullHours fullMinutes fullSeconds
- local hasYears hasMonths hasDays hasHours hasMinutes hasSeconds
- local witherPrecision output
- local displayYears displayMonths displayDays displayHours displayMinutes displaySeconds
-
- argSeconds="$1"; # read arg1 (seconds)
- argPrecision="$2"; # read arg2 (precision)
- precision=2; # set default precision
-
- # Check that between one and two arguments is supplied
- if ! { [[ $# -ge 1 ]] && [[ $# -le 2 ]]; }; then
- yell "ERROR:Invalid number of arguments:$# . Exiting.";
- returnState="error_input"; fi
-
- # Check that argSeconds provided
- if [[ $# -ge 1 ]]; then
- ## Check that argSeconds is a positive integer
- if [[ "$argSeconds" =~ ^[[:digit:]]+$ ]]; then
- :
- else
- yell "ERROR:argSeconds not a digit.";
- returnState="error_input";
- fi
- else
- yell "ERROR:No argument provided. Exiting.";
- exit 1;
- fi
-
- # Consider whether argPrecision was provided
- if [[ $# -eq 2 ]]; then
- # Check that argPrecision is a positive integer
- if [[ "$argPrecision" =~ ^[[:digit:]]+$ ]] && [[ "$argPrecision" -gt 0 ]]; then
- precision="$argPrecision";
- else
- yell "ERROR:argPrecision not a positive integer. (is $argPrecision ). Leaving early.";
- returnState="error_input";
- fi;
- else
- :
- fi;
-
- remainder="$argSeconds" ; # seconds
- ## Calculate full years Y, update remainder
- fullYears=$(( remainder / (365*24*60*60) ));
- remainder=$(( remainder - (fullYears*365*24*60*60) ));
- ## Calculate full months M, update remainder
- fullMonths=$(( remainder / (30*24*60*60) ));
- remainder=$(( remainder - (fullMonths*30*24*60*60) ));
- ## Calculate full days D, update remainder
- fullDays=$(( remainder / (24*60*60) ));
- remainder=$(( remainder - (fullDays*24*60*60) ));
- ## Calculate full hours H, update remainder
- fullHours=$(( remainder / (60*60) ));
- remainder=$(( remainder - (fullHours*60*60) ));
- ## Calculate full minutes M, update remainder
- fullMinutes=$(( remainder / (60) ));
- remainder=$(( remainder - (fullMinutes*60) ));
- ## Calculate full seconds S, update remainder
- fullSeconds=$(( remainder / (1) ));
- remainder=$(( remainder - (remainder*1) ));
- ## Check which fields filled
- if [[ $fullYears -gt 0 ]]; then hasYears="true"; else hasYears="false"; fi
- if [[ $fullMonths -gt 0 ]]; then hasMonths="true"; else hasMonths="false"; fi
- if [[ $fullDays -gt 0 ]]; then hasDays="true"; else hasDays="false"; fi
- if [[ $fullHours -gt 0 ]]; then hasHours="true"; else hasHours="false"; fi
- if [[ $fullMinutes -gt 0 ]]; then hasMinutes="true"; else hasMinutes="false"; fi
- if [[ $fullSeconds -ge 0 ]]; then hasSeconds="true"; else hasSeconds="false"; fi
-
- ## Determine which fields to display (see ISO-8601:2004 §4.4.3.2)
- witherPrecision="false"
-
- ### Years
- if $hasYears && [[ $precision -gt 0 ]]; then
- displayYears="true";
- witherPrecision="true";
- else
- displayYears="false";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ### Months
- if $hasMonths && [[ $precision -gt 0 ]]; then
- displayMonths="true";
- witherPrecision="true";
- else
- displayMonths="false";
- fi;
- if $witherPrecision && [[ $precision -gt 0 ]]; then
- displayMonths="true";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ### Days
- if $hasDays && [[ $precision -gt 0 ]]; then
- displayDays="true";
- witherPrecision="true";
- else
- displayDays="false";
- fi;
- if $witherPrecision && [[ $precision -gt 0 ]]; then
- displayDays="true";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ### Hours
- if $hasHours && [[ $precision -gt 0 ]]; then
- displayHours="true";
- witherPrecision="true";
- else
- displayHours="false";
- fi;
- if $witherPrecision && [[ $precision -gt 0 ]]; then
- displayHours="true";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ### Minutes
- if $hasMinutes && [[ $precision -gt 0 ]]; then
- displayMinutes="true";
- witherPrecision="true";
- else
- displayMinutes="false";
- fi;
- if $witherPrecision && [[ $precision -gt 0 ]]; then
- displayMinutes="true";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ### Seconds
-
- if $hasSeconds && [[ $precision -gt 0 ]]; then
- displaySeconds="true";
- witherPrecision="true";
- else
- displaySeconds="false";
- fi;
- if $witherPrecision && [[ $precision -gt 0 ]]; then
- displaySeconds="true";
- fi;
- if $witherPrecision; then ((precision--)); fi;
-
- ## Determine whether or not the "T" separator is needed to separate date and time elements
- if ( $displayHours || $displayMinutes || $displaySeconds); then
- displayDateTime="true"; else displayDateTime="false"; fi
-
- ## Construct duration output string
- output="P"
- if $displayYears; then
- output=$output$fullYears"Y"; fi
- if $displayMonths; then
- output=$output$fullMonths"M"; fi
- if $displayDays; then
- output=$output$fullDays"D"; fi
- if $displayDateTime; then
- output=$output"T"; fi
- if $displayHours; then
- output=$output$fullHours"H"; fi
- if $displayMinutes; then
- output=$output$fullMinutes"M"; fi
- if $displaySeconds; then
- output=$output$fullSeconds"S"; fi
-
- ## Output duration string to stdout
- echo "$output" && returnState="true";
-
- #===Determine function return code===
- if [ "$returnState" = "true" ]; then
- return 0;
- elif [ "$returnState" = "error_input" ]; then
- yell "ERROR:input";
- return 1;
- else
- yell "ERROR:Unknown";
- return 2;
- fi
-
-} # Get duration (ex: PT10M4S )
-
-#==BEGIN sample code==
-echo "Precision 6 duration:$(timeDuration "$(date +%s)" 6)"
-echo "Precision 5 duration:$(timeDuration "$(date +%s)" 5)"
-echo "Precision 4 duration:$(timeDuration "$(date +%s)" 4)"
-echo "Precision 3 duration:$(timeDuration "$(date +%s)" 3)"
-echo "Precision 2 duration:$(timeDuration "$(date +%s)" 2)"
-echo "Precision 1 duration:$(timeDuration "$(date +%s)" 1)"
-echo "Precision 6 duration:$(timeDuration $((60+60*60+60*60*24+60*60*24*30+60*60*24*365 - (60+60*60+60*60*24+60*60*24*30) )) 6)"
-echo "Zero seconds:$(timeDuration "0")";
-echo "Parsing argument provided to script:\"$*\""; timeDuration "$@"
-#==END sample code==
-
-# Author: Steven Baltakatei Sandoval
-# License: GPLv3+