update(unitproc/bkdstcountdown):Refactor
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Fri, 3 Mar 2023 23:31:54 +0000 (23:31 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Fri, 3 Mar 2023 23:31:54 +0000 (23:31 +0000)
unitproc/bkdstcountdown

index 4e3efe81182423551053a93fc0ac34f5d7281394..17ff7fa75a741824c0d139a21ac68ed5e2a582dc 100755 (executable)
@@ -1,74 +1,64 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# Description: Outputs days until next timezone discontinuity
+# Depends: GNU Coreutils 8.32 (date), zdump 2.35, Bash 5.1.16
+#   BK-2020-03: yell(), die(), must()
+# Version: 0.1.0
 
 
-# Description: This script outputs days until the next time zone
-# discontinuity using 'zdump' and 'date'.
-
-#=================ADJUST ME=======================
-SCRIPT_TZ="America/Los_Angeles" # Timezone to check for discontinuities
-#=================================================
+# User config
+script_tz="America/Los_Angeles"; # Timezone to check for discontinuities
 
 yell() { echo "$0: $*" >&2; } # Yell, Die, Try Three-Fingered Claw technique; # Ref/Attrib: https://stackoverflow.com/a/25515370
 die() { yell "$*"; exit 111; }
 
 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 $*"; }
-
-# Declare variables
-declare -a datesDiscontArray #array
-
-SCRIPT_YEAR=$(date +%Y)
-SCRIPT_YEAR_NEXT=$(( $(date +%Y) + 1))
-SCRIPT_YEAR_NEXT2=$(( $(date +%Y) + 2))
-SCRIPT_RUN_DATE_SECONDS=$(date +%s)
+must() { "$@" || die "cannot $*"; }
+main() {
+    declare -a datesDiscontArray; #array
 
 
-# Save zdump output for SCRIPT_YEAR (for how multiline data saved in variable, see https://stackoverflow.com/a/613580 )
-datesDiscont="$(zdump -c "$SCRIPT_YEAR","$SCRIPT_YEAR_NEXT2" -v $SCRIPT_TZ | grep "$SCRIPT_YEAR\|$SCRIPT_YEAR_NEXT" |  awk '{ print $2 " " $3 " " $4 " " $5 " " $6 " " $7 }'; echo)"
-if [ -z "$datesDiscont" ]; then
-    echo "No time discontinuity this year.";
-    exit 1;
-fi;
+    # plumbing
+    script_year="$(date +%Y)";
+    script_year_next="$(( script_year + 1 ))";
+    script_year_next2="$(( script_year + 2 ))";
+    script_run_date_seconds="$(date +%s)";
 
 
-###yell "DEBUG:datesDiscont----------";
-###echo "$datesDiscont" 1>&2;
-###yell "DEBUG:-----------";
+    # Get discontinuity dates from zdump (see https://stackoverflow.com/a/613580 )
+    datesDiscont="$(zdump -c "$script_year","$script_year_next2" -v $script_tz | \
+      grep "$script_year\|$script_year_next" | \
+      awk '{ print $2 " " $3 " " $4 " " $5 " " $6 " " $7 }'; echo)"; # get dates
+    if [[ -z "$datesDiscont" ]]; then
+        yell "STATUS:No time discontinuity this year.";
+        exit 1;
+    fi;
 
 
-# Count lines in datesDiscont (for counting lines in a variable, see https://stackoverflow.com/a/6314682 )
-#datesDiscontLineCount=$(echo "$datesDiscont" | wc -l)
+    # Convert datesDiscont into array
+    while read -r line; do
+        tunix="$(date --date="$line" +%s)"; # get unix epoch seconds
+        datesDiscontArray+=("$tunix");
+    done < <(printf "%s\n" "$datesDiscont");
 
 
-# Convert datesDiscont into array (for how to process each line in a multiline variable, see https://superuser.com/a/284226 )
-while IFS= read -r line; do
-    #echo "$line"
-    #datesDiscontArray+="$line"
-    datesDiscontArray+=($(date --date="$line" +%s))
-    #echo ${datesDiscontArray[-1]}
-done <<< "$datesDiscont"
-#yell ${datesDiscontArray[@]}
+    # Sort datesDiscontArray
+    while read -r line; do
+        datesDiscontArray+=("$line");
+    done < <(printf "%s\n" "${datesDiscontArray[@]}" | sort);
 
 
-# Sort datesDiscontArray (see https://stackoverflow.com/a/11789688 )
-IFS=$'\n' datesDiscontArray=($(sort <<<"${datesDiscontArray[*]}"))
-unset IFS
+    # # Get earliest date in datesDiscontArray that isn't in the past.
+    for discontinuityDate in "${datesDiscontArray[@]}"; do
+        if [[ $discontinuityDate -gt $script_run_date_seconds ]]; then
+            nextDiscontDate="$discontinuityDate";
+            break;
+        fi;
+    done;
 
 
-###yell "DEBUG:";
-###yell "DEBUG:datesDiscontArray:";
-###yell "${datesDiscontArray[@]}";
-###yell "DEBUG:";
+    # Check that nextDiscontDate is not empty
+    if [[ -z "$nextDiscontDate" ]]; then
+        die "FATAL:nextDiscontDate empty";
+    fi;
 
 
-# Get earliest date in datesDiscontArray that isn't in the past.
-for discontinuityDate in "${datesDiscontArray[@]}"; do
-    ###yell "DEBUG:Discontinuity date (seconds):"$discontinuityDate
-    ###yell "DEBUG:SCRIPT_RUN_DATE_SECONDS     :"$SCRIPT_RUN_DATE_SECONDS
-    if [ $discontinuityDate -gt $SCRIPT_RUN_DATE_SECONDS ]; then
-       ###yell "DEBUG:Date in future."
-       nextDiscontDate="$discontinuityDate"
-       break
-    fi
-done
+    # Calculate days until next discontinuity date
+    output="$(( ( nextDiscontDate - script_run_date_seconds )/86400 )) days";
+    printf "%s\n" "$output";
 
 
-# Check that nextDiscontDate is not empty
-if [ -z "$nextDiscontDate" ]; then
-    echo "ERROR:nextDiscontDate empty"
-fi;
-   
+}; # main program
 
 
-###yell "DEBUG:nextDiscontDate:$nextDiscontDate";
-###yell "DEBUG:SCRIPT_RUN_DATE_SECONDS:$SCRIPT_RUN_DATE_SECONDS";
+main "$@";
 
 
-echo $(( ( $nextDiscontDate - $SCRIPT_RUN_DATE_SECONDS )/86400 ))" days" # Days until next discontinuity date
+# Author: Steven Baltakatei Sandoval
+# License: GPLv3+