style(unitproc):timeDuration:Changed variable names
[BK-2020-03.git] / unitproc / bktemp-timeDuration
CommitLineData
7ad273d8
SBS
1#!/bin/bash
2
3# Desc: Template to indicate time duration in ISO-8601 format
4
5yell() { echo "$0: $*" >&2; } # Yell, Die, Try Three-Fingered Claw technique; # Ref/Attrib: https://stackoverflow.com/a/25515370
6die() { yell "$*"; exit 111; }
7try() { "$@" || die "cannot $*"; }
8timeDuration(){
1a6ae9e0 9 # Desc: Given seconds, output ISO-8601 duration string
7ad273d8
SBS
10 # Ref/Attrib: ISO-8601:2004(E), §4.4.4.2 Representations of time intervals by duration and context information
11 # Note: "1 month" ("P1M") is assumed to be "30 days" (see ISO-8601:2004(E), §2.2.1.2)
1a6ae9e0
SBS
12 # Usage: timeDuration [1:seconds] ([2:precision])
13 # Version: 1.0.2
7ad273d8
SBS
14 # Input: arg1: seconds as base 10 integer >= 0 (ex: 3601)
15 # arg2: precision level (optional; default=2)
16 # Output: stdout: ISO-8601 duration string (ex: "P1H1S", "P2Y10M15DT10H30M20S")
1a6ae9e0
SBS
17 # exit code 0: success
18 # exit code 1: error_input
7ad273d8 19 # Example: 'timeDuration 111111 3' yields 'P1DT6H51M'
25f31c30 20 # Depends: date 8 (gnucoreutils), yell,
1a6ae9e0 21 local returnState argSeconds argPrecision remainder precision witherPrecision
25f31c30
SBS
22 local fullYears fullMonths fullDays fullHours fullMinutes fullSeconds
23 local displayYears displayMonths displayDays displayHours displayMinutes displaySeconds
24 local hasYears hasMonths hasDays hasHours hasMinutes hasSeconds
25
1a6ae9e0
SBS
26 argSeconds="$1"; # read arg1 (seconds)
27 argPrecision="$2"; # read arg2 (precision)
7ad273d8 28 precision=2; # set default precision
7ad273d8
SBS
29
30 # Check that between one and two arguments is supplied
31 if ! { [[ $# -ge 1 ]] && [[ $# -le 2 ]]; }; then
32 yell "ERROR:Invalid number of arguments:$# . Exiting.";
1a6ae9e0 33 returnState="error_input"; fi
7ad273d8 34
1a6ae9e0 35 # Check that argSeconds provided
7ad273d8 36 if [[ $# -ge 1 ]]; then
1a6ae9e0
SBS
37 ## Check that argSeconds is a positive integer
38 if [[ "$argSeconds" =~ ^[[:digit:]]+$ ]]; then
25ecb96f 39 :
7ad273d8 40 else
1a6ae9e0
SBS
41 yell "ERROR:argSeconds not a digit.";
42 returnState="error_input";
7ad273d8
SBS
43 fi
44 else
45 yell "ERROR:No argument provided. Exiting.";
46 exit 1;
47 fi
48
1a6ae9e0 49 # Consider whether argPrecision was provided
7ad273d8 50 if [[ $# -eq 2 ]]; then
1a6ae9e0
SBS
51 # Check that argPrecision is a positive integer
52 if [[ "$argPrecision" =~ ^[[:digit:]]+$ ]] && [[ "$argPrecision" -gt 0 ]]; then
53 precision="$argPrecision";
7ad273d8 54 else
1a6ae9e0
SBS
55 yell "ERROR:argPrecision not a positive integer. (is $argPrecision ). Leaving early.";
56 returnState="error_input";
7ad273d8
SBS
57 fi;
58 else
25ecb96f 59 :
7ad273d8
SBS
60 fi;
61
1a6ae9e0 62 remainder="$argSeconds" ; # seconds
7ad273d8
SBS
63 ## Calculate full years Y, update remainder
64 fullYears=$(( remainder / (365*24*60*60) ));
65 remainder=$(( remainder - (fullYears*365*24*60*60) ));
7ad273d8
SBS
66 ## Calculate full months M, update remainder
67 fullMonths=$(( remainder / (30*24*60*60) ));
68 remainder=$(( remainder - (fullMonths*30*24*60*60) ));
7ad273d8
SBS
69 ## Calculate full days D, update remainder
70 fullDays=$(( remainder / (24*60*60) ));
71 remainder=$(( remainder - (fullDays*24*60*60) ));
7ad273d8
SBS
72 ## Calculate full hours H, update remainder
73 fullHours=$(( remainder / (60*60) ));
74 remainder=$(( remainder - (fullHours*60*60) ));
7ad273d8
SBS
75 ## Calculate full minutes M, update remainder
76 fullMinutes=$(( remainder / (60) ));
77 remainder=$(( remainder - (fullMinutes*60) ));
7ad273d8
SBS
78 ## Calculate full seconds S, update remainder
79 fullSeconds=$(( remainder / (1) ));
80 remainder=$(( remainder - (remainder*1) ));
7ad273d8
SBS
81 ## Check which fields filled
82 if [[ $fullYears -gt 0 ]]; then hasYears="true"; else hasYears="false"; fi
83 if [[ $fullMonths -gt 0 ]]; then hasMonths="true"; else hasMonths="false"; fi
84 if [[ $fullDays -gt 0 ]]; then hasDays="true"; else hasDays="false"; fi
85 if [[ $fullHours -gt 0 ]]; then hasHours="true"; else hasHours="false"; fi
86 if [[ $fullMinutes -gt 0 ]]; then hasMinutes="true"; else hasMinutes="false"; fi
87 if [[ $fullSeconds -gt 0 ]]; then hasSeconds="true"; else hasSeconds="false"; fi
88
89 ## Determine which fields to display (see ISO-8601:2004 §4.4.3.2)
90 witherPrecision="false"
91
92 ### Years
93 if $hasYears && [[ $precision -gt 0 ]]; then
94 displayYears="true";
95 witherPrecision="true";
96 else
97 displayYears="false";
98 fi;
99 if $witherPrecision; then ((precision--)); fi;
100
101 ### Months
102 if $hasMonths && [[ $precision -gt 0 ]]; then
103 displayMonths="true";
104 witherPrecision="true";
105 else
106 displayMonths="false";
107 fi;
108 if $witherPrecision && [[ $precision -gt 0 ]]; then
109 displayMonths="true";
110 fi;
111 if $witherPrecision; then ((precision--)); fi;
112
113 ### Days
114 if $hasDays && [[ $precision -gt 0 ]]; then
115 displayDays="true";
116 witherPrecision="true";
117 else
118 displayDays="false";
119 fi;
120 if $witherPrecision && [[ $precision -gt 0 ]]; then
121 displayDays="true";
122 fi;
123 if $witherPrecision; then ((precision--)); fi;
124
125 ### Hours
126 if $hasHours && [[ $precision -gt 0 ]]; then
127 displayHours="true";
128 witherPrecision="true";
129 else
130 displayHours="false";
131 fi;
132 if $witherPrecision && [[ $precision -gt 0 ]]; then
133 displayHours="true";
134 fi;
135 if $witherPrecision; then ((precision--)); fi;
136
137 ### Minutes
138 if $hasMinutes && [[ $precision -gt 0 ]]; then
139 displayMinutes="true";
140 witherPrecision="true";
141 else
142 displayMinutes="false";
143 fi;
144 if $witherPrecision && [[ $precision -gt 0 ]]; then
145 displayMinutes="true";
146 fi;
147 if $witherPrecision; then ((precision--)); fi;
148
149 ### Seconds
150
151 if $hasSeconds && [[ $precision -gt 0 ]]; then
152 displaySeconds="true";
153 witherPrecision="true";
154 else
155 displaySeconds="false";
156 fi;
157 if $witherPrecision && [[ $precision -gt 0 ]]; then
158 displaySeconds="true";
159 fi;
160 if $witherPrecision; then ((precision--)); fi;
161
7ad273d8 162 ## Determine whether or not the "T" separator is needed to separate date and time elements
7ad273d8
SBS
163 if ( $displayHours || $displayMinutes || $displaySeconds); then
164 displayDateTime="true"; else displayDateTime="false"; fi
165
166 ## Construct duration output string
167 OUTPUT="P"
168 if $displayYears; then
169 OUTPUT=$OUTPUT$fullYears"Y"; fi
170 if $displayMonths; then
171 OUTPUT=$OUTPUT$fullMonths"M"; fi
172 if $displayDays; then
173 OUTPUT=$OUTPUT$fullDays"D"; fi
174 if $displayDateTime; then
175 OUTPUT=$OUTPUT"T"; fi
176 if $displayHours; then
177 OUTPUT=$OUTPUT$fullHours"H"; fi
178 if $displayMinutes; then
179 OUTPUT=$OUTPUT$fullMinutes"M"; fi
180 if $displaySeconds; then
181 OUTPUT=$OUTPUT$fullSeconds"S"; fi
182
183 ## Output duration string to stdout
1a6ae9e0 184 echo "$OUTPUT" && returnState="true";
7ad273d8
SBS
185
186 #===Determine function return code===
187 if [ "$returnState" = "true" ]; then
188 return 0;
1a6ae9e0
SBS
189 elif [ "$returnState" = "error_input" ]; then
190 yell "ERROR:input";
7ad273d8 191 return 1;
1a6ae9e0
SBS
192 else
193 yell "ERROR:Unknown";
194 return 2;
7ad273d8
SBS
195 fi
196
197} # Get duration (ex: PT10M4S )
198
199#==BEGIN sample code==
200echo "Precision 6 duration:$(timeDuration "$(date +%s)" 6)"
201echo "Precision 5 duration:$(timeDuration "$(date +%s)" 5)"
202echo "Precision 4 duration:$(timeDuration "$(date +%s)" 4)"
203echo "Precision 3 duration:$(timeDuration "$(date +%s)" 3)"
204echo "Precision 2 duration:$(timeDuration "$(date +%s)" 2)"
205echo "Precision 1 duration:$(timeDuration "$(date +%s)" 1)"
206echo "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)"
207timeDuration "$@"
208#==END sample code==
209
210# Author: Steven Baltakatei Sandoval
211# License: GPLv3+