feat(user/bkdatev): Add macOS BSD date compatibility
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Tue, 23 May 2023 01:19:11 +0000 (01:19 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Tue, 23 May 2023 01:19:11 +0000 (01:19 +0000)
- Note(user/bkdatev): v0.2.2 -> v0.3.0

unitproc/bkt-insertStr
user/bkdatev

index 6cea251bbba541001398509e6ad6ae3398a89de3..5fdbf93abc130ad008136b12ccb4dd4345aa3b8c 100755 (executable)
@@ -1,21 +1,23 @@
 #!/usr/bin/env bash
 # Desc: Insert string into provided string
 
-yell() { echo "$0:${FUNCNAME[*]}: $*" >&2; }
+yell() { echo "$0: $*" >&2; }
 die() { yell "$*"; exit 111; }
 must() { "$@" || die "cannot $*"; }
-
 insertStr() {
-    # Desc: Inserts a
+    # Desc: Inserts a string into another string at a specified position.
     # Input: arg1: str   str_rec  String to receive insertion
     #        arg2: int   pos      Insertion position (0 = append to front)
     #        arg3: str   str_ins  String to be inserted
     # Output: stdout:    Combined string
-    # Version: 0.0.1
+    # Version: 0.0.2
     # Depends: BK-2020-03: yell(), die(), must()
     # Ref/Attrib: * BK-2020-03: https://gitlab.com/baltakatei/baltakatei-exdev/
-    
-    local str_rec pos str_ins;
+    #             * Cooper, Mendel. “Advanced Bash-Scripting Guide: Manipulating Strings”. tldp.org https://tldp.org/LDP/abs/html/string-manipulation.html
+
+    local str_rec pos str_ins re len_str_rec;
+    local pfx_pos_start pfx_len pfx;
+    local sfx_pos_start sfx_len sfx;
 
     # Check args
     if [[ $# -ne 3 ]]; then
@@ -31,7 +33,6 @@ insertStr() {
 
     # Calculate string stats
     len_str_rec="${#str_rec}";
-    len_str_ins="${#str_ins}";
 
     # Form prefix
     pfx_pos_start="0";
@@ -44,7 +45,7 @@ insertStr() {
     sfx="${str_rec:$sfx_pos_start:$sfx_len}";
 
     # Print output to stdout
-    printf "%s%s%s\n" "$pfx" "$str_ins" "$sfx";    
+    printf "%s%s%s\n" "$pfx" "$str_ins" "$sfx";
 }; # Insert string provided at indicated position via stdout
 
 
index 22ff3103bdaeded393da434eec4d54af77e2d283..f2f92ec99e93801a422f1547316f50f2f2c86329 100755 (executable)
@@ -2,7 +2,7 @@
 # Desc: Baltakatei's verbose date command
 # Usage: bkdatev [args]
 # Example: bkdatev --date="2001-09-11T09:02:59-04"
-# Version: 0.2.2
+# Version: 0.3.0
 # Ref/Attrib: [1] "ISO 8601". Wikipedia. https://en.wikipedia.org/wiki/ISO_8601
 #             [2] "Changing the Locale in Wine" https://stackoverflow.com/a/16428951
 #             [3] "Shanghai vs Beijing" https://bugs.launchpad.net/ubuntu/+source/libgweather/+bug/228554
 #         * Locations chosen for population, personal signifiance, and spatial coverage.
 #         * For International Atomic Time (TAI), use offsets from UTC provided in `/usr/share/zoneinfo/leap-seconds.list`.
 
+yell() { echo "$0: $*" >&2; }
+die() { yell "$*"; exit 111; }
+must() { "$@" || die "cannot $*"; }
+insertStr() {
+    # Desc: Inserts a string into another string at a specified position.
+    # Input: arg1: str   str_rec  String to receive insertion
+    #        arg2: int   pos      Insertion position (0 = append to front)
+    #        arg3: str   str_ins  String to be inserted
+    # Output: stdout:    Combined string
+    # Version: 0.0.2
+    # Depends: BK-2020-03: yell(), die(), must()
+    # Ref/Attrib: * BK-2020-03: https://gitlab.com/baltakatei/baltakatei-exdev/
+    #             * Cooper, Mendel. “Advanced Bash-Scripting Guide: Manipulating Strings”. tldp.org https://tldp.org/LDP/abs/html/string-manipulation.html
+
+    local str_rec pos str_ins re len_str_rec;
+    local pfx_pos_start pfx_len pfx;
+    local sfx_pos_start sfx_len sfx;
+
+    # Check args
+    if [[ $# -ne 3 ]]; then
+        yell "ERROR:Invalid argument count:$#";
+        return 1; fi;
+    re='^[0-9]+$';
+    if [[ ! "$2" =~ $re ]]; then
+        yell "ERROR:Not an int:$2";
+        return 1; fi;
+    str_rec="$1";
+    pos="$2";
+    str_ins="$3";
+
+    # Calculate string stats
+    len_str_rec="${#str_rec}";
+
+    # Form prefix
+    pfx_pos_start="0";
+    pfx_len="$pos";
+    pfx="${str_rec:$pfx_pos_start:$pfx_len}";
+
+    # Form suffix
+    sfx_pos_start="$(( pos ))";
+    sfx_len="$(( len_str_rec - pos ))";
+    sfx="${str_rec:$sfx_pos_start:$sfx_len}";
+
+    # Print output to stdout
+    printf "%s%s%s\n" "$pfx" "$str_ins" "$sfx";
+}; # Insert string provided at indicated position via stdout
 line_sep() {
     # Input: var: n_ln
     local skip_every=4;
@@ -21,21 +67,53 @@ line_sep() {
     fi;
     return 0;
 }; # periodically print separating blank line
+get_tz_offset() {
+    # Desc: Get from 'date' the timezone UTC offset in a way
+    #   compatible with both GNU Coreutils and BSD versions.
+    # Input: env var: TZ  (time zone for date; e.g. 'America/Denver')
+    # Depends: date (GNU Coreutils 8.32 or BSD), rev
+    local ntz ntz ntz_out;
+    local last2;
+
+    # Get numeric time zone string in way compatible with GNU Coreutils and BSD
+    ntz="$(date "+%z")"; # e.g. "+0530"
+
+    # Check if last two characters are trailing zeros that can be removed.
+    last2="${ntz:3:2}"; # assumes $ntz is 5 characters (i.e. "±HHMM")
+    #last2="$(rev <<< $ntz)" && last2="${last2:0:2}" && last2="$(rev <<< "$last2")";
+    if [[ "$last2" == "00" ]]; then
+        ## ntz_out is truncated by 2 characters
+        ntz_out="${ntz:0:-2}";
+    else
+        ## ntz_out is ntz with semicolon inserted after HH
+        ntz_out="$(insertStr "$ntz" 3 ":" )";
+    fi;
+    
+    # Output via stdout
+    printf "%s" "$ntz_out";
+}; # Format numeric time zone (for BSD date compatibility)
 print_dateline() {
     # Input: var: $id
     #        var: $fs_1
     #        var: $fs_2
     #        var: $fs_3
     #        args: $@
+    #        env var: TZ (time zone for date; e.g. 'America/Denver')
     # Output: stdout
     # Depends: printf, date
+    #          get_tz_offset()
     # Ref/Attrib: * Truncate string in printf https://stackoverflow.com/a/46812677
-    local s_1 s_2 s_3 s_4;
+    local s_1 s_2 s_2_tz s_3 s_4;
 
     s_1="$id";
-    s_2="$(date "$@" "$fs_1")";
-    s_3="$(date "$@" "$fs_2")";
-    s_4="$(date "$@" "$fs_3")";
+    s_2="$(date "$@" "$fs_1")"; # ISO-8601 without numeric timezone
+    s_3="$(date "$@" "$fs_2")"; # Alternate ISO-8601 expressions
+    s_4="$(date "$@" "$fs_3")"; # locale-specific date strings
+
+    # Append numeric timezone to $s_2 with appropriate format
+    #   (e.g. '-07' for 'Arizona', '+05:45' for 'Asia/Kathmandu')
+    s_2_tz="$(get_tz_offset)";
+    s_2="$( printf "%s%s" "$s_2" "$s_2_tz" )";
 
     printf "%-10.10s %-25.25s (%-20.20s) (%s)" "$s_1" "$s_2" "$s_3" "$s_4";
     printf "\n";
@@ -47,7 +125,7 @@ main() {
     unset LC_TIME; # Fall back to time zone-specific locale settings.
     
     # format strings
-    fs_iso8601="+%Y-%m-%dT%H:%M:%S%:::z"; # typical ISO-8601
+    fs_iso8601="+%Y-%m-%dT%H:%M:%S"; # typical ISO-8601 without timezone
     fs_iso8601_etc="+%G-W%V-%u, %Y-%j"; # alternate ISO-8601 dates
     fs_locale="+%Z; %A; %c"; # locale-specific date strings
 
@@ -316,3 +394,6 @@ main() {
 }; # main program
 
 main "$@";
+
+# Author: Steven Baltakatei Sandoval
+# License: GPLv3+