/home/alex/dev/calendar.sh (1)

From RaySoft
#!/bin/bash -
# ------------------------------------------------------------------------------
# calendar.sh
# ===========
#
# Scope     Native
# Copyright (C) 2024 by RaySoft, Zurich, Switzerland
# License   GNU General Public License (GPL) 2.0
#           https://www.gnu.org/licenses/gpl2.txt
#
# ------------------------------------------------------------------------------

set -o 'noglob' -o 'nounset' -o 'pipefail' # -o 'xtrace' -o 'errexit'

# ------------------------------------------------------------------------------

WEEKDAY_NAMES='Mo Tu We Th Fr Sa Su'

# ------------------------------------------------------------------------------

DATE=('/usr/local/bin/gdate')
PRINTF=('/usr/local/bin/gprintf')

# ------------------------------------------------------------------------------

# Get the current year, month and day
read -r 'cur_year' 'cur_month' 'cur_day' <<<"$("${DATE[@]}" '+%Y %-m %-d')"

# Get the day of week of the first day of the current month
first_weekday="$("${DATE[@]}" '+%u' --date="${cur_year}-${cur_month}-1")"

# Get the day of week of the last day of the current month
last_month_day="$( \
  "${DATE[@]}" '+%-d' --date="${cur_year}-${cur_month}-1 +1 month -1 day" \
)"

# Get the week numbers for the current month
weeks=()

for ((day = 1; day <= last_month_day; day++)); do
  week="$("${DATE[@]}" '+%-V' --date="${cur_year}-${cur_month}-${day}")"

  if [[ ! "${weeks[*]}" =~ ${week} ]]; then
    weeks+=("${week}")
  fi
done

# ------------------------------------------------------------------------------

"${PRINTF[@]}" 'Week %-18d' "${weeks[@]}"

echo

for week in "${weeks[@]}"; do
  "${PRINTF[@]}" '%-23s' "${WEEKDAY_NAMES}"
done

echo

for ((day = 1; day <= $((first_weekday - 1)); day++)); do
  echo -n '   '
done

for ((day = 1; day <= last_month_day; day++)); do
  if [[ ${cur_day} -eq ${day} ]]; then
    "${PRINTF[@]}" '\033[1;31m%-3d\033[0m' ${day}
  else
    "${PRINTF[@]}" '%-3d' ${day}
  fi

  if [[ $(( (day + first_weekday - 1) % 7 )) -eq 0 ]]; then
    echo -n '  '
  fi
done

echo

# ------------------------------------------------------------------------------

exit 0

Usage

~/dev/calendar.sh

Output:

Week 52                Week 1                 Week 2                 Week 3   ...
Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We Th Fr Sa Su   Mo Tu We ...
                  1    2  3  4  5  6  7  8    9  10 11 12 13 14 15   16 17 18 ...