+ # 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 -gt 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 )
+timeUntilNextDay(){
+ # Desc: Report seconds until next day.
+ # Version: 1.0.2
+ # Output: stdout: integer seconds until next day
+ # Output: exit code 0 if stdout > 0; 1 if stdout = 0; 2 if stdout < 0
+ # Usage: timeUntilNextDay
+ # Usage: if ! myTTL="$(timeUntilNextDay)"; then yell "ERROR in if statement"; exit 1; fi
+ # Depends: date 8, echo 8, yell, try
+
+ local returnState timeCurrent timeNextDay secondsUntilNextDay returnState