[continued from previous message]
#secAtz secBtz secAprtz secBprtz
((sec${v}${p}tz=sec${v}-(tz${v}s*neg_tz${v}) )) #neg_tzA neg_tzB
if ((sec${v}${p}tz<0))
then ((min${v}${p}tz+=((sec${v}${p}tz-59)/60) , sec${v}${p}tz=(sec${v}${p}tz%60+60)%60))
elif ((sec${v}${p}tz>59))
then ((min${v}${p}tz+=(sec${v}${p}tz/60) , sec${v}${p}tz%=60))
fi
#minAtz minBtz minAprtz minBprtz
((min${v}${p}tz+=min${v}-(tz${v}m*neg_tz${v}) ))
if ((min${v}${p}tz<0))
then ((hour${v}${p}tz+=((min${v}${p}tz-59)/60) , min${v}${p}tz=(min${v}${p}tz%60+60)%60))
elif ((min${v}${p}tz>59))
then ((hour${v}${p}tz+=(min${v}${p}tz/60) , min${v}${p}tz%=60))
fi
#hourAtz hourBtz hourAprtz hourBprtz
((hour${v}${p}tz+=hour${v}-(tz${v}h*neg_tz${v}) ))
if ((hour${v}${p}tz<0))
then ((day${v}${p}tz+=((hour${v}${p}tz-23)/24) , hour${v}${p}tz=(hour${v}${p}tz%24+24)%24))
elif ((hour${v}${p}tz>23))
then ((day${v}${p}tz+=(hour${v}${p}tz/24) , hour${v}${p}tz%=24))
fi
#dayAtz dayBtz dayAprtz dayBprtz
((day${v}${p}tz+=day${v}))
if ((day${v}${p}tz<1))
then var=$(month_maxday "$((month${v}==1 ? 12 : month${v}-1))" "$((year${v}))")
((day${v}${p}tz+=var))
if ((month${v}>1))
then ((--month${v}${p}tz))
else ((month${v}${p}tz-=month${v}))
fi
elif var=$(month_maxday "$((month${v}))" "$((year${v}))")
((day${v}${p}tz>var))
then ((++month${v}${p}tz))
((day${v}${p}tz%=var))
fi
#monthAtz monthBtz monthAprtz monthBprtz
((month${v}${p}tz+=month${v}))
if ((month${v}${p}tz<1))
then ((--year${v}${p}tz))
((month${v}${p}tz+=12))
elif ((month${v}${p}tz>12))
then ((++year${v}${p}tz))
((month${v}${p}tz%=12))
fi
((year${v}${p}tz+=year${v})) #yearAtz yearBtz yearAprtz yearBprtz
done
#modulus as (a%b + b)%b to avoid negative remainder.
#<
https://www.geeksforgeeks.org/modulus-on-negative-numbers/>
if [[ $yearAtz ]]
then (( yearA=yearAtz , monthA=monthAtz , dayA=dayAtz,
hourA=hourAtz , minA=minAtz , secA=secAtz ,
tzAh=0 , tzAm=0 , tzAs=0
))
fi
if [[ $yearBtz ]]
then (( yearB=yearBtz , monthB=monthBtz , dayB=dayBtz,
hourB=hourBtz , minB=minBtz , secB=secBtz ,
tzBh=0 , tzBm=0 , tzBs=0
))
fi
if [[ $yearAprtz ]]
then date1_iso8601_pr=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d:%02d\\n \
"$yearAprtz" "$monthAprtz" "${dayAprtz}" \
"${hourAprtz}" "${minAprtz}" "${secAprtz}" \
"${TZ_pos%1}" "$TZh" "$TZm" "$TZs")
fi
if [[ $yearBprtz ]]
then date2_iso8601_pr=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d:%02d\\n \
"$yearBprtz" "$monthBprtz" "${dayBprtz}" \
"${hourBprtz}" "${minBprtz}" "${secBprtz}" \
"${TZ_pos%1}" "$TZh" "$TZm" "$TZs")
fi
elif [[ ! $unix2$OPTVERBOSE && $tzA$tzB$TZ = *+([A-Za-z_])* ]]
then #echo "warning: input DATE or \$TZ contains timezone ID or name. Support requires package \`date'" >&2
unset tzA tzB tzAh tzBh tzAm tzBm tzAs tzBs TZh TZm TZs
else unset tzA tzB tzAh tzBh tzAm tzBm tzAs tzBs TZh TZm TZs
fi #Offset is *from* UTC, while $TZ is *to* UTC.
#sort `UTC' dates (if no `date' package)
if [[ ! $unix2 ]] && ((
(yearA>yearB)
|| ( (yearA==yearB) && (monthA>monthB) )
|| ( (yearA==yearB) && (monthA==monthB) && (dayA>dayB) )
|| ( (yearA==yearB) && (monthA==monthB) && (dayA==dayB) && (hourA>hourB) )
|| ( (yearA==yearB) && (monthA==monthB) && (dayA==dayB) && (hourA==hourB) && (minA>minB) )
|| ( (yearA==yearB) && (monthA==monthB) && (dayA==dayB) && (hourA==hourB) && (minA==minB) && (secA>secB) )
))
then neg_range=-1
for varname in inputA yearA monthA dayA hourA minA secA \
yearAtz monthAtz dayAtz hourAtz minAtz secAtz \
yearAprtz monthAprtz dayAprtz hourAprtz minAprtz secAprtz \
tzA tzAh tzAm tzAs neg_tzA date1_iso8601 date1_iso8601_pr
do #swap $varA/$varB or $var1/$var2 values
[[ $varname = *A* ]] && p=A q=B || p=1 q=2
eval "buf=\"\$$varname\""
eval "$varname=\"\$${varname/$p/$q}\" ${varname/$p/$q}=\"\$buf\""
done
unset varname p q
set -- "$2" "$1" "${@:3}"
fi
##Count leap years and sum leap and non leap years days,
for ((y_test=(yearA+1);y_test<yearB;++y_test))
do
#((y_test==0)) && continue #ISO8601 counts year zero, proleptic gregorian/julian do not
is_leapyear $y_test && ((++leapcount))
((++years_between))
((monthcount += 12))
done
##count days in non and leap years
(( daycount_leap_years = (366 * leapcount) ))
(( daycount_years = (365 * (years_between - leapcount) ) ))
#date2 days so far this year (this month)
#days in prior months `this' year
((month_tgt = (yearA==yearB ? monthA : 0) ))
for ((month_test=(monthB-1);month_test>month_tgt;--month_test))
do
if ((month_test==2)) && is_leapyear $yearB
then (( fullmonth_days += 29 ))
else (( fullmonth_days += ${YEAR_MONTH_DAYS[month_test-1]} ))
fi
((++monthcount))
done
#date1 days until end of `that' year
#days in prior months `that' year
((yearA==yearB)) ||
for ((month_test=(monthA+1);month_test<13;++month_test))
do
if ((month_test==2)) && is_leapyear $yearA
then (( fullmonth_days += 29 ))
else (( fullmonth_days += ${YEAR_MONTH_DAYS[month_test-1]} ))
fi
((++monthcount))
done
((fullmonth_days_save = fullmonth_days))
#some info about input dates and their context..
date3_month_max_day=$(month_maxday "$((monthB==1 ? 12 : monthB-1))" "$yearB")
date1_month_max_day=$(month_maxday "$monthA" "$yearA")
date1_year_days_adj=$(year_days_adj "$monthA" "$yearA")
#set years and months
(( y = years_between ))
(( mo = ( monthcount - ( (years_between) ? (years_between * 12) : 0) ) ))
#days left
if ((yearA==yearB && monthA==monthB))
then
((d_left = (dayB - dayA) ))
((d_left_save = d_left))
elif ((dayA<dayB))
then
((++mo))
((fullmonth_days += date1_month_max_day))
((d_left = (dayB - dayA) ))
((d_left_save = d_left))
elif ((dayA>dayB))
then #refinement rules (or hacks)
((d_left = ( (date3_month_max_day>=dayA) ? (date3_month_max_day-dayA) : (date1_month_max_day-dayA) ) + dayB ))
((d_left_save = (date1_month_max_day-dayA) + dayB ))
if ((dayA>date3_month_max_day && date3_month_max_day<date1_month_max_day && dayB>1))
then
((dayB>=dayA-date3_month_max_day)) && ##addon2 -- prevents negative days
((d_left -= date1_month_max_day-date3_month_max_day))
((d_left==0 && ( (24-hourA)+hourB<24 || ( (24-hourA)+hourB==24 && (60-minA)+minB<60 ) || ( (24-hourA)+hourB==24 && (60-minA)+minB==60 && (60-secA)+secB<60 ) ) && (++d_left) )) ##addon3 -- prevents breaking down a full month
if ((d_left < 0))
then if ((w))
then ((--w , d_left+=7))
elif ((mo))
then ((--mo , w=date3_month_max_day/7 , d_left+=date3_month_max_day%7))
elif ((y))
then ((--y , mo+=11 , w=date3_month_max_day/7 , d_left+=date3_month_max_day%7))
fi
fi
elif ((dayA>date3_month_max_day)) #dayB==1
then
((d_left = (date1_month_max_day - dayA + date3_month_max_day + dayB) ))
((w = d_left/7 , d_left%=7))
if ((mo))
then ((--mo))
elif ((y))
then ((--y , mo+=11))
fi
fi
else #`dayA' equals `dayB'
((++mo))
((fullmonth_days += date1_month_max_day))
#((d_left_save = d_left)) #set to 0
fi
((h += (24-hourA)+hourB))
if ((h && h<24))
then if ((d_left))
then ((--d_left , ++ok))
elif ((mo))
then ((--mo , d_left+=date3_month_max_day-1 , ++ok))
elif ((y))
then ((--y , mo+=11 , d_left+=date3_month_max_day-1 , ++ok))
fi
fi
((h %= 24))
((m += (60-minA)+minB))
if ((m && m<60))
then if ((h))
then ((--h))
elif ((d_left))
then ((--d_left , h+=23 , ++ok))
elif ((mo))
then ((--mo , d_left+=date3_month_max_day-1 , h+=23 , ++ok))
elif ((y))
then ((--y , mo+=11 , d_left+=date3_month_max_day-1 , h+=23 , ++ok))
fi
fi
((m %= 60))
((s = (60-secA)+secB))
if ((s && s<60))
then if ((m))
then ((--m))
elif ((h))
then ((--h , m+=59))
elif ((d_left))
then ((--d_left , h+=23 , m+=59 , ++ok))
elif ((mo))
then ((--mo , d_left+=date3_month_max_day-1 , h+=23 , m+=59 , ++ok))
elif ((y))
then ((--y , mo+=11 , d_left+=date3_month_max_day-1 , h+=23 , m+=59 , ++ok))
fi
fi
((s %= 60))
((ok && (--d_left_save) ))
((m += s/60 , s %= 60))
((h += m/60 , m %= 60))
((d_left_save += h/24))
((d_left += h/24 , h %= 24))
((y += mo/12 , mo %= 12))
((w += d_left/7))
((d = d_left%7))
#total sum of full days { range = unix2-unix1 }
((d_sum = ( (d_left_save) + (fullmonth_days + daycount_years + daycount_leap_years) ) ))
((range = (d_sum * 3600 * 24) + (h * 3600) + (m * 60) + s))
#generate unix times arithmetically?
((GETUNIX)) && { echo ${neg_range%1}${range} ;unset GETUNIX ;return ${ret:-0} ;}
if [[ ! $unix2 ]]
then badges="$badges#"
if ((
(yearA>1970 ? yearA-1970 : 1970-yearA)
> (yearB>1970 ? yearB-1970 : 1970-yearB)
))
then var=$yearB-$monthB-${dayB}T$hourB:$minB:$secB varname=B #utc times
else var=$yearA-$monthA-${dayA}T$hourA:$minA:$secA varname=A
fi
var=$(GETUNIX=1 DATE_CMD=false OPTVERBOSE=1 OPTRR= TZ= \
mainf $EPOCH $var) || ((ret+=$?))
if [[ $varname = B ]]
then ((unix2=var , unix1=unix2-range))
else ((unix1=var , unix2=unix1+range))
fi
if ((OPTRR)) #make RFC-5322 format string
then if ! { date2_iso8601_pr=$(get_timef "$unix2" "$TIME_RFC5322_FMT") &&
date1_iso8601_pr=$(get_timef "$unix1" "$TIME_RFC5322_FMT") ;}
then #calculate Day Of Week (bash v<3.1)
date2_diw=$(get_day_in_week $((unix2-( ( (TZh*60*60)+(TZm*60)+TZs)*TZ_neg) )) )
date1_diw=$(get_day_in_week $((unix1-( ( (TZh*60*60)+(TZm*60)+TZs)*TZ_neg) )) )
date2_iso8601_pr=$(printf \
'%s, %02d %s %04d %02d:%02d:%02d %s%02d:%02d:%02d\n' \
"${date2_diw:0:3}" "${dayBprtz:-${dayBtz:-$dayB}}" \
"${MONTH_OF_YEAR[${monthBprtz:-${monthBtz:-$monthB}}-1]:0:3}" \
"${yearBprtz:-${yearBtz:-$yearB}}" \
"${hourBprtz:-${hourBtz:-$hourB}}" \
"${minBprtz:-${minBtz:-$minB}}" \
"${secBprtz:-${secBtz:-$secB}}" \
"${TZ_pos%1}" "$TZh" "$TZm" "$TZs")
date1_iso8601_pr=$(printf \
'%s, %02d %s %04d %02d:%02d:%02d %s%02d:%02d:%02d\n' \
"${date1_diw:0:3}" "${dayAprtz:-${dayAtz:-$dayA}}" \
"${MONTH_OF_YEAR[${monthAprtz:-${monthAtz:-$monthA}}-1]:0:3}" \
"${yearAprtz:-${yearAtz:-$yearA}}" \
"${hourAprtz:-${hourAtz:-$hourA}}" \
"${minAprtz:-${minAtz:-$minA}}" \
"${secAprtz:-${secAtz:-$secA}}" \
"${TZ_pos%1}" "$TZh" "$TZm" "$TZs")
fi
fi
fi
#single unit time durations (when `bc' is available)
if ((OPTT || OPTVERBOSE<3))
then if [[ $BASH_VERSION ]]
then bc=( $(bc <<<" /* round argument 'x' to 'd' digits */
define r(x, d) { auto r, s; if(0 > x) { return -r(-x, d); };
r = x + 0.5*10^-d; s = scale; scale = d; r = r*10/10;
scale = s; return r; }; scale = ($SCL + 1);
r( (${years_between:-0} + ( (${range:-0} - ( (${daycount_years:-0} + ${daycount_leap_years:-0}) * 24 * 60 * 60) ) / (${date1_year_days_adj:-0} * 24 * 60 * 60) ) ) , $SCL); /** YEARS **/
r( (${monthcount:-0} + ( (${range:-0} - (${fullmonth_days_save:-0} * 24 * 60 * 60) ) / (${date1_month_max_day:-0} * 24 * 60 * 60) ) ) , $SCL); /** MONTHS **/
r( (${range:-0} / ( 7 * 24 * 60 * 60)) , $SCL); /** WEEKS **/
r( (${range:-0} / (24 * 60 * 60)) , $SCL); /** DAYS **/
r( (${range:-0} / (60 * 60)) , $SCL); /** HOURS **/
r( (${range:-0} / 60) , $SCL); /** MINUTES **/")
)
bcy=${bc[0]} bcmo=${bc[1]} bcw=${bc[2]} bcd=${bc[3]} bch=${bc[4]} bcm=${bc[5]}
#ARRAY: 0=YEARS 1=MONTHS 2=WEEKS 3=DAYS 4=HOURS 5=MINUTES
else typeset -F $SCL bcy bcmo bcw bcd bch bcm
bcy="${years_between:-0} + ( (${range:-0} - ( (${daycount_years:-0} + ${daycount_leap_years:-0}) * 24 * 60 * 60.) ) / (${date1_year_days_adj:-0} * 24 * 60 * 60.) )" #YEARS
bcmo="${monthcount:-0} + ( (${range:-0} - (${fullmonth_days_save:-0} * 24 * 60 * 60.) ) / (${date1_month_max_day:-0} * 24 * 60 * 60.) )" #MONTHS
bcw="${range:-0} / ( 7 * 24 * 60 * 60.)" #WEEKS
bcd="${range:-0} / (24 * 60 * 60.)" #DAYS
bch="${range:-0} / (60 * 60.)" #HOURS
bcm="${range:-0} / 60." #MINUTES
fi
#choose layout of single units
if ((OPTT || !OPTLAYOUT))
then #layout one
spcr=' | ' #spacer
prHelpf ${OPTTy:+${bcy}} && range_pr="${bcy} year$SS"
prHelpf ${OPTTmo:+${bcmo}} && range_pr="${range_pr}${range_pr:+$spcr}${bcmo} month$SS"
prHelpf ${OPTTw:+${bcw}} && range_pr="${range_pr}${range_pr:+$spcr}${bcw} week$SS"
prHelpf ${OPTTd:+${bcd}} && range_pr="${range_pr}${range_pr:+$spcr}${bcd} day$SS"
prHelpf ${OPTTh:+${bch}} && range_pr="${range_pr}${range_pr:+$spcr}${bch} hour$SS"
prHelpf ${OPTTm:+${bcm}} && range_pr="${range_pr}${range_pr:+$spcr}${bcm} min$SS"
prHelpf $range ;((!OPTT||OPTTs)) && range_pr="$range_pr${range_pr:+$spcr}$range sec$SS"
((OPTT&&OPTV)) && range_pr="${range_pr%%*([$IFS])}" #bug in ksh93u+ ${var% *}
else #layout two
((n = ${#range}+SCL+1)) #range in seconds is the longest string
prHelpf ${bcy} $n && range_pr=Year$SS$'\t'$SSS${bcy}
prHelpf ${bcmo} $n && range_pr="$range_pr"$'\n'Month$SS$'\t'$SSS${bcmo}
prHelpf ${bcw} $n && range_pr="$range_pr"$'\n'Week$SS$'\t'$SSS${bcw}
prHelpf ${bcd} $n && range_pr="$range_pr"$'\n'Day$SS$'\t'$SSS${bcd}
prHelpf ${bch} $n && range_pr="$range_pr"$'\n'Hour$SS$'\t'$SSS${bch}
prHelpf ${bcm} $n && range_pr="$range_pr"$'\n'Min$SS$'\t'$SSS${bcm}
prHelpf $range $((n - (SCL>0 ? (SCL+1) : 0) ))
range_pr="$range_pr"$'\n'Sec$SS$'\t'$SSS$range
range_pr="${range_pr#*([$IFS])}"
#
https://www.themathdoctors.org/should-we-put-zero-before-a-decimal-point/
((OPTLAYOUT>1)) && { p= q=. ;for ((p=0;p<SCL;++p)) ;do q="${q}0" ;done
range_pr="${range_pr// ./0.}" range_pr="${range_pr}${q}" ;}
fi
unset SS SSS
fi
#set printing array with shell results
sh=("$y" "$mo" "$w" "$d" "$h" "$m" "$s")
((y<0||mo<0||w<0||d<0||h<0||m<0||s<0)) && ret=${ret:-1} #negative unit error
# Debugging
if ((DEBUG))
then
#!#
debugf "$@"
fi
#print results
if ((!OPTVERBOSE))
then if [[ ! $date1_iso8601_pr$date1_iso8601 ]]
then date1_iso8601=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d:%02d\\n \
"$yearA" "$monthA" "$dayA" \
"$hourA" "$minA" "$secA" \
"${neg_tzA%1}" "$tzAh" "$tzAm" "$tzAs")
date1_iso8601=${date1_iso8601%%*(:00)}
else date1_iso8601_pr=${date1_iso8601_pr%%*(:00)} #remove excess zeroes
fi
if [[ ! $date2_iso8601_pr$date2_iso8601 ]]
then date2_iso8601=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d:%02d\\n \
"$yearB" "$monthB" "$dayB" \
"$hourB" "$minB" "$secB" \
"${neg_tzB%1}" "$tzBh" "$tzBm" "$tzBs")
date2_iso8601=${date2_iso8601%%*(:00)}
else date2_iso8601_pr=${date2_iso8601_pr%%*(:00)}
fi
printf '%s%s\n%s%s%s\n%s%s%s\n%s\n' \
DATES "${OPTDD+#}${badges}${neg_range%1}" \
"${date1_iso8601_pr:-${date1_iso8601:-$inputA}}" ''${unix1:+$'\t'} "$unix1" \
"${date2_iso8601_pr:-${date2_iso8601:-$inputB}}" ''${unix2:+$'\t'} "$unix2" \
RANGES
fi
prfmt='%dY %02dM %02dW %02dD %02dh %02dm %02ds' #print format for the compound range
((OPTVERBOSE>3)) && prfmt='%dY%02dM%02dW%02dD%02dh%02dm%02ds' #AST `date -E' style
((OPTVERBOSE<2 || OPTVERBOSE>2)) && printf "${prfmt}\n" "${sh[@]}"
((OPTVERBOSE<3)) && printf '%s\n' "${range_pr:-$range secs}"
return ${ret:-0}
}
#execute result checks against `datediff' and `date'
#check manually in case of divergence as this function is overloaded
#beware of opt -R and unset $TZ and offsets (we defaults to UTC while `date' may set random offsets)
function debugf
{
unset iA iB tA tB dd ddout y_dd mo_dd w_dd d_dd h_dd m_dd s_dd range_check unix1t unix2t checkA_pr checkB_pr checkA_pr_dow checkB_pr_dow checkA_utc checkB_utc date_cmd_save TZ_save brk
date_cmd_save="${DATE_CMD}" DATE_CMD=date TZ_save=$TZ TZ=UTC${TZ##*$GLOBUTC}
[[ $2 = *[Tt:]*[+-]$GLOBTZ && $1 = *[Tt:]*[+-]$GLOBTZ ]] || echo warning: input dates are missing offset/tz bits! >&2
iB="${2:-${inputB}}" iA="${1:-${inputA}}"
iB="${iB:0:25}" iA="${iA:0:25}"
((${#iB}==10)) && iB=${iB}T00:00:00
((${#iA}==10)) && iA=${iA}T00:00:00
((${#iB}==19)) && iB="${iB}+00:00"
((${#iA}==19)) && iA="${iA}+00:00"
iB=${iB/-00:00/+00:00} iA=${iA/-00:00/+00:00}
#utc time strings
tB=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d\\n \
"$yearB" "$monthB" "$dayB" \
"$hourB" "$minB" "$secB" \
"${neg_tzB%1}" $tzBh $tzBm)
tA=$(printf \
%04d-%02d-%02dT%02d:%02d:%02d%s%02d:%02d\\n \
"$yearA" "$monthA" "$dayA" \
"$hourA" "$minA" "$secA" \
"${neg_tzA%1}" $tzAh $tzAm)
tB=${tB:0:25} tA=${tA:0:25}
tB=${tB/-00:00/+00:00} tA=${tA/-00:00/+00:00}
if [[ $date_cmd_save = false ]]
then
if ((TZs)) || [[ $TZ = *:*:*:* ]] || [[ $tzA = *:*:*:* ]] || [[ $tzB = *:*:*:* ]]
then echo "warning: \`datediff' and \`date' may not take offsets with seconds" >&2
((ret+=230))
fi
if ((TZh||TZm))
then checkB_pr=$(datefun -Iseconds $iB)
checkA_pr=$(datefun -Iseconds $iA)
else checkB_pr=$date2_iso8601_pr checkA_pr=$date1_iso8601_pr
fi
if ((OPTRR))
then checkB_pr_dow=$(datefun "$iB")
checkA_pr_dow=$(datefun "$iA")
fi
checkB_utc=$(TZ=UTC datefun -Iseconds $iB)
checkA_utc=$(TZ=UTC datefun -Iseconds $iA)
#`date' iso offset must not exceed minute precision [+-]XX:XX !
#check generated unix times against `date'
unix2t=$(datefun "$iB" +%s)
unix1t=$(datefun "$iA" +%s)
range_check=$((unix2t-unix1t))
fi
if ((OPTRR))
then checkB_pr_dow="${checkB_pr_dow:-$date2_iso8601_pr}"
checkA_pr_dow="${checkA_pr_dow:-$date1_iso8601_pr}"
fi
#compound range check against `datediff'
#`datediff' offset range is between -14h and +14h!
ddout=$(datediff -f'%Y %m %w %d %H %M %S' "$tA" "$tB") || ((ret+=250))
read y_dd mo_dd w_dd d_dd h_dd m_dd s_dd <<<"$ddout"
dd=(${y_dd#-} $mo_dd $w_dd $d_dd $h_dd $m_dd $s_dd)
DATE_CMD="$date_cmd_save" TZ=$TZ_save
{
{
{ [[ ${date2_iso8601_pr:0:25} = $checkB_pr ]] &&
[[ ${date1_iso8601_pr:0:25} = $checkA_pr ]] ;} ||
{ [[ ${date2_iso8601_pr:0:3} = ${checkB_pr_dow:0:3} ]] &&
[[ ${date1_iso8601_pr:0:3} = ${checkA_pr_dow:0:3} ]] ;}
} &&
[[ $tB = ${checkB_utc:-$tB} ]] &&
[[ $tA = ${checkA_utc:-$tA} ]] &&
[[ $unix1 = ${unix1t:-$unix1} && $unix2 = ${unix2t:-$unix2} ]] &&
[[ $range = "${range_check:-$range}" ]] &&
[[ ${sh[*]} = "${dd[*]:-${sh[*]}}" ]]
} || { #brk='\n'
echo -ne "\033[2K" >&2
echo ${brk+-e} "\
sh=${sh[*]} dd=${dd[*]} | $brk"\
"$iA $iB | $brk"\
"${range:-unavail} ${range_check:-unavail} | $brk"\
"${date1_iso8601_pr:0:25} $checkA_pr | $brk"\
"${date2_iso8601_pr:0:25} $checkB_pr | $brk"\
"${date1_iso8601_pr:0:3} ${checkA_pr_dow:0:3} | $brk"\
"${date2_iso8601_pr:0:3} ${checkB_pr_dow:0:3} | $brk"\
"$tB $checkB_utc | $brk"\
"$tA $checkA_utc | $brk"\
"$unix1 $unix1t | $brk"\
"$unix2 $unix2t | $brk"\
"${date_cmd_save%date}"
((ret+=1))
}
#((DEBUG>1)) && return ${ret:-0} #!#
((DEBUG>1)) && exit ${ret:-0} #!#
return 0
}
## Parse options
while getopts 01234567890DdeFf:hlmRr@tuv opt
do case $opt in
[0-9]) SCL="$SCL$opt"
;;
d) ((++DEBUG))
;;
D) [[ ${DATE_CMD} = false ]] && OPTDD=1 ;DATE_CMD=false
;;
e) OPTE=1 OPTL=
;;
F) ((++OPTFF))
;;
f) INPUT_FMT="$OPTARG" OPTF=1 #input format string for `BSD date'
;;
h) while read
do [[ "$REPLY" = \#\ v* ]] && echo "$REPLY $SHELL" && break
done <"$0"
echo "$HELP" ;exit
;;
l) OPTL=1 OPTE=
;;
m) OPTM=1
;;
R) OPTRR=1
;;
r|@) OPTR=1
;;
t) ((++OPTLAYOUT))
;;
u) OPTU=1
;;
v) ((++OPTVERBOSE, ++OPTV))
;;
\?) exit 1
;;
esac
done
shift $((OPTIND -1)); unset opt
#set proper environment!
SCL="${SCL:-1}" #scale defaults
((OPTU)) && TZ=UTC #set UTC time zone
export TZ
#test for BSD or GNU date for datefun()
[[ ${DATE_CMD} ]] ||
if DATE_CMD=date;
! ${DATE_CMD} --version
then if gdate --version
then DATE_CMD=gdate
elif command -v date
then BSDDATE=1
else DATE_CMD=false
fi
fi >/dev/null 2>&1
#stdin input (skip it for option -F)
[[ ${1//[$IFS]}$OPTFF = $GLOBOPT ]] && opt="$1" && shift
if ((!($#+OPTFF) )) && [[ ! -t 0 ]]
then
globtest="*([$IFS])@($GLOBDATE?(+([$SEP])$GLOBTIME)|$GLOBTIME)*([$IFS])@($GLOBDATE?(+([$SEP])$GLOBTIME)|$GLOBTIME)?(+([$IFS])$GLOBOPT)*([$IFS])" #glob for two ISO8601 dates and possibly pos arg option for single unit range
while IFS= read -r || [[ $REPLY ]]
do ar=($REPLY) ;((${#ar[@]})) || continue
if ((!$#))
then set -- "$REPLY" ;((OPTL)) && break
#check if arg contains TWO ISO8601 dates and break
if ((${#ar[@]}==3||${#ar[@]}==2)) && [[ \ $REPLY = @(*[$IFS]$GLOBOPT*|$globtest) ]]
then set -- $REPLY ;[[ $1 = $GLOBOPT ]] || break
fi
else if ((${#ar[@]}==2)) && [[ \ $REPLY = @(*[$IFS]$GLOBOPT|$globtest) ]]
then set -- "$@" $REPLY
else set -- "$@" "$REPLY"
fi ;break
fi
done ;unset ar globtest REPLY
[[ ${1//[$IFS]} = $GLOBOPT ]] && opt="$1" && shift
fi
[[ $opt ]] && set -- "$@" "$opt"
#set single time unit
opt="${opt:-${@: -1}}" opt="${opt//[$IFS]}"
if [[ $opt$OPTFF = $GLOBOPT ]]
then OPTT=1 OPTVERBOSE=2 OPTLAYOUT=
case $opt in
[yY]) OPTTy=1;;
[mM][oO]) OPTTmo=1;;
[wW]) OPTTw=1;;
[dD]) OPTTd=1;;
[hH]) OPTTh=1;;
[mM]) OPTTm=1;;
[sS]) OPTTs=1;;
esac ;set -- "${@:1:$#-1}"
else OPTTy=1 OPTTmo=1 OPTTw=1 OPTTd=1 OPTTh=1 OPTTm=1 OPTTs=1
fi ;unset opt
#caveat: `gnu date' understands `-d[a-z]', do `-d[a-z]0' to pass.
#whitespace trimming
if (($#>1))
then set -- "${1#"${1%%[!$IFS]*}"}" "${2#"${2%%[!$IFS]*}"}" "${@:3}"
set -- "${1%"${1##*[!$IFS]}"}" "${2%"${2##*[!$IFS]}"}" "${@:3}"
elif (($#))
then set -- "${1#"${1%%[!$IFS]*}"}" ;set -- "${1%"${1##*[!$IFS]}"}"
fi
if ((OPTL))
then for YEAR
do is_year "$YEAR" || continue
if ! is_leapyear_verbose "$YEAR"
then (($?>1)) && RET=2 ;RET="${RET:-$?}"
fi
done ;exit $RET
elif ((OPTE))
then for YEAR
do is_year "$YEAR" || continue
DATE=$(easterf "$YEAR") ;echo $DATE
done
elif ((OPTM))
then for DATE_Y #fill in months and days
do if [[ $DATE_Y = +([0-9]) ]]
then set -- ;OPTM=2
for ((M=1;M<=12;++M)) ;do set -- "$@" "${DATE_Y}-$M" ;done
else set -- "$DATE_Y" ;PHASE_SKIP=
fi
for DATE_M
do if [[ $DATE_M = +([0-9])[$SEP]+([0-9]) ]]
then set -- ;OPTM=2
DMAX=$(month_maxday "${DATE_M#*[$SEP]}" "${DATE_M%[$SEP]*}")
for ((D=1;D<=DMAX;++D)) ;do set -- "$@" "${DATE_M}-$D" ;done
else set -- "$DATE_M" ;PHASE_SKIP=
fi
for DATE
do set -- ${DATE//[$SEP]/ } #input is ISO8601
phase_of_the_moon "$3" "$2" "$1"
done
done
done
elif ((OPTFF))
then friday_13th "$@"
else
#-r, unix times
if ((OPTR && $#>1))
then set -- @"${1#@}" @"${2#@}" "${@:3}"
elif ((OPTR && $#))
then set -- @"${1#@}"
fi
mainf "$@"
fi
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)