feat(user/bk_this-date): Add script to print dow for given dom 0.5.1
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Sun, 25 Sep 2022 11:22:44 +0000 (11:22 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Sun, 25 Sep 2022 11:22:44 +0000 (11:22 +0000)
- Note: script name: bk_this-date-in-recent-years.sh

- Note: The script prints out an iso-8601 date string followed by the
  day of the week for the most recent 10 years or a specified date
  range. Useful for determining likely years a month-day combination
  occured when the day of the week is known.

user/bk_this-date-in-recent-years.sh [new file with mode: 0644]

diff --git a/user/bk_this-date-in-recent-years.sh b/user/bk_this-date-in-recent-years.sh
new file mode 100644 (file)
index 0000000..f072ca6
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/env bash
+# Desc: Prints days
+# Depends: date (GNU Coreutils 8.32)
+# Version: 0.0.1
+# Ref/Attrib: [1] Template:This date in recent years https://en.wikipedia.org/wiki/Template:This_date_in_recent_years
+#             [2] Removing leading zeros before passing a shell variable to another command https://stackoverflow.com/a/11130324
+
+declare -g yearRange;  # range of years to consider
+
+yell() { echo "$0: $*" >&2; }      #o Yell, Die, Try Three-Fingered Claw technique
+die() { yell "$*"; exit 111; }     #o Ref/Attrib: https://stackoverflow.com/a/25515370
+try() { "$@" || die "cannot $*"; } #o
+vbm() {
+    # Description: Prints verbose message ("vbm") to stderr if opVerbose is set to "true".
+    # Usage: vbm "DEBUG :verbose message here"
+    # Version 0.2.0
+    # Input: arg1: string
+    #        vars: opVerbose
+    # Output: stderr
+    # Depends: bash 5.1.16, GNU-coreutils 8.30 (echo, date)
+
+    if [ "$opVerbose" = "true" ]; then
+       functionTime="$(date --iso-8601=ns)"; # Save current time in nano seconds.
+       echo "[$functionTime]:$0:""$*" 1>&2;  # Display argument text.
+    fi
+
+    # End function
+    return 0; # Function finished.
+} # Displays message if opVerbose true
+showUsage() {
+    # Desc: Display script usage information
+    # Usage: showUsage
+    # Version 0.0.2
+    # Input: none
+    # Output: stdout
+    # Depends: GNU-coreutils 8.30 (cat)
+    cat <<'EOF'
+    USAGE:
+        bk_this-date-in-recent-years.sh [ options ] [str day of month]
+
+    OPTIONS:
+        -h, --help
+                Display help information.
+        --version
+                Display script version.
+        -v, --verbose
+                Display debugging info.
+        -r, --iso-range
+                Specify year range (iso-8601 period), e.g.
+                "2010/2020". By default, most recent 10
+                years are considered.
+        --
+                Indicate end of options.
+
+    EXAMPLE:
+      bk_this_date-in-recent-years.sh "05-11"
+      bk_this_date-in-recent-years.sh -r "1990/2020" "05-11"
+      bk_this_date-in-recent-years.sh -r "1990/2020" -- "05-11"
+EOF
+} # Display information on how to use this script.
+processArgs() {
+    # Desc: Processes arguments provided to script.
+    # Usage: processArgs "$@"
+    # Version: 1.0.0
+    # Input: "$@"          (list of arguments provided to the function)
+    #   yearRange            Iso date range to consider (e.g. "1999/2020").
+    # Output: Sets following variables used by other functions:
+    #   opVerbose            Indicates verbose mode enable status.  (ex: "true", "false")
+    #   opIsoRange           Indicates that an iso-8601 date range is specified. (ex: "true", "false")
+    #   yearRange            Iso date range to consider (e.g. "1999/2020").
+    #   arrayPosArgs         Array of remaining positional argments
+    # Depends:
+    #   yell()           Displays messages to stderr.
+    #   vbm()            Displays messsages to stderr if opVerbose set to "true".
+    #   showUsage()      Displays usage information about parent script.
+    #   showVersion()    Displays version about parent script.
+    #   arrayPosArgs     Global array for storing non-option positional arguments (i.e. arguments following the `--` option).
+    # External dependencies: bash (5.1.16), echo
+    # Ref./Attrib.:
+    #  [1]: Marco Aurelio (2014-05-08). "echo that outputs to stderr". https://stackoverflow.com/a/23550347
+    #  [2]: "Handling positional parameters" (2018-05-12). https://wiki.bash-hackers.org/scripting/posparams
+    
+    # Initialize function
+    vbm "DEBUG:processArgs function called."
+
+    # Perform work
+    while [ ! $# -eq 0 ]; do   # While number of arguments ($#) is not (!) equal to (-eq) zero (0).
+       #yell "DEBUG:Starting processArgs while loop." # Debug stderr message. See [1].
+        #yell "DEBUG:Provided arguments are:""$*"      # Debug stderr message. See [1].
+       case "$1" in
+           -h | --help) showUsage; exit 1;; # Display usage.
+           --version) showVersion; exit 1;; # Show version
+           -v | --verbose) opVerbose="true"; vbm "DEBUG:Verbose mode enabled.";; # Enable verbose mode. See [1].
+            -r | --iso-range)
+                opIsoRange="true"; vbm "DEBUG:Accepting iso-8601 year range."; # Accept iso-8601 year range.
+                shift;
+                yearRange="$1";;
+            --) # End of all options. See [2].
+                shift;
+                for arg in "$@"; do
+                    vbm "DEBUG:adding to arrayPosArgs:$arg";
+                    arrayPosArgs+=("$arg");
+                done;
+                break;;
+            -*) showUsage; yell "ERROR: Unrecognized option."; exit 1;; # Display usage
+            *) for arg in "$@"; do
+                   vbm "DEBUG:adding to arrayPosArgs:$arg";
+                   arrayPosArgs+=("$arg");
+               done;
+               break;;
+       esac
+       shift
+    done
+    
+    # End function
+    vbm "DEBUG:processArgs function ended."
+    return  0; # Function finished.
+} # Evaluate script options from positional arguments (ex: $1, $2, $3, etc.).
+validatePosArgs() {
+    # Input: arrayPosArgs  array with positional arguments
+    #        opVerbose    bool indicates to vbm() to display verbose text
+    #        opIsoRange   bool indicates to use a user-provided year range
+    #        yearRange    str  iso-8601 year range provided by -r, --iso-range option
+    
+    # Validate year $range
+    re='^[0-9]+/[0-9]+$'; # Simply check (int)/(int). Don't address Gregorian Calendar here.
+    if [[ $opIsoRange == "true" && ! "$yearRange" =~ $re ]] ; then
+        showUsage;
+        yell "ERROR:Not a valid date range (e.g. 2010/2022):$yearRange";
+        return 1;
+    fi;
+    return 0;
+}; # Validate arguments
+main() {
+    # Input: arrayPosArgs  array with positional arguments
+    #        opVerbose    bool indicates to vbm() to display verbose text
+    #        opIsoRange   bool indicates to use a user-provided year range
+    #        yearRange    str  iso-8601 year range provided by -r, --iso-range option
+    # Output: stdout: dates with days of the week (newline delimited)
+    # Depends: date (GNU Coreutils 8.32)
+    # Depends: processArgs(), yell(), vbm(), showUsage(), showVersion(), validatePosArgs()
+    local dom yc ymin ymax;
+
+    # Check input
+    processArgs "$@";
+    if ! validatePosArgs; then
+        die "FATAL:Invalid positional arguments:$(declare -p arrayPosArgs)";
+    fi;
+
+    # Define year range
+    if [[ ! $opIsoRange == "true" ]]; then
+        ## Default: Most recent 10 years
+        yc="10";                 # count of years to consider
+        ymax="$(date +%Y)";      # highest year to consider
+        ymin="$((ymax - yc))"; # earliest year to consider
+    else
+        ## Provided via -r,--iso-range option
+        ymin="$(echo "$yearRange" | cut -d'/' -f1)";
+        ymin="$((10#$ymin))"; # strip leading zeroes. See [2]
+        ymax="$(echo "$yearRange" | cut -d'/' -f2)"; # See [2]
+        ymax="$((10#$ymax))"; # strip leading zeroes. See [2]
+        yc="$((ymax - ymin + 1))";
+    fi;
+    # yell "DEBUG:ymin:$ymin";
+    # yell "DEBUG:ymax:$ymax";
+    # yell "DEBUG:yc  :$yc";
+
+    # Check year range
+    if ! [[ $(( ymax - ymin )) -ge 0 ]]; then die "FATAL:Invalid year range:$yearRange"; fi;
+    
+    # Print Output
+    ## Get day of month (first positional argument)
+    dom="${arrayPosArgs[0]}";
+    for (( year = ymin; year <= ymax; year++ )); do
+        dstr="$year-$dom";
+        date +%Y-%m-%d\ %A --date="$dstr";
+        # printf "DEBUG:dom :%s\n" "$dom";
+        # printf "DEBUG:ymax:%s\n" "$ymax";
+        # printf "DEBUG:ymin:%s\n" "$ymin";
+        # printf "DEBUG:year:%s\n" "$year";
+        # printf "DEBUG:dstr:%s\n" "$dstr";
+    done;    
+}; # main program
+
+main "$@";
+
+
+
+# Author: Steven Baltakatei Sandoval
+# License: GPLv3+
+
+# Ref/Attrib (depends)
+
+    # date (GNU coreutils) 8.32
+    # Copyright (C) 2020 Free Software Foundation, Inc.
+    # License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
+    # This is free software: you are free to change and redistribute it.
+    # There is NO WARRANTY, to the extent permitted by law.
+
+    # Written by David MacKenzie.