+#!/bin/bash
+
+yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
+die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status
+must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails
+dateDuration() {
+ # Desc: Given two date strings, output seconds duration
+ # Example: dateDuration 2012-06-30 2012-07-01 # Yields 86401 because leap second
+ # Version 0.0.1
+ # Depends: GNU Coreutils 9.4 (date, sed), GNU Bash 5.2.21
+ # References: [1] “"right" tz database (zoneinfo) files and GPS-based NTP” https://www.ucolick.org/~sla/leapsecs/right+gps.html
+
+ date1="$1";
+ date2="$2";
+ # Check args
+ if [[ -z "$date1" ]]; then die "FATAL:Invalid first date provided:${date1}"; fi;
+ if [[ -z "$date2" ]]; then die "FATAL:Invalid second date provided:${date2}"; fi;
+ if [[ $# -gt 2 ]]; then die "FATAL:Too many arguments."; fi;
+ ## Convert @-specified unix epoch into right unix epoch (rue)
+ re='@.*';
+ if [[ "$date1" =~ $re ]] || [[ "$date2" =~ $re ]]; then
+ die "FATAL:@-specified unix epoch detected. Why are you using me?";
+ fi;
+
+ # Use right unix epoch to account for leap seconds.
+ export TZ=right/UTC; # See [1]
+
+ # Convert date strings into Unix epoch
+ unixEpoch1="$(must date --date="$date1" +%s)";
+ unixEpoch2="$(must date --date="$date2" +%s)";
+
+ # Calculate duration
+ duration="$((unixEpoch2 - unixEpoch1))";
+ duration="$(sed -e 's/^-//' <<<"$duration"; )";
+
+ printf "%s\n" "$duration";
+};
+
+# Examples
+dateDuration 2026-06-30 2026-07-01; # 86400 seconds
+dateDuration 2012-06-30 2012-07-01; # 86401 seconds (leap second)