#!/usr/bin/env bash if [[ -z "$1" ]]; then cat << EOF reldate - Format or adjust dates Usage: reldate Examples: reldate "2025-12-12" # Output: 2025-12-12 reldate "+1d" # Output: tomorrow's date reldate "-1w" # Output: date 1 week ago reldate "+2m" # Output: date 2 months from now reldate "-1y" # Output: date 1 year ago reldate today # Output: today's date reldate tomorrow # Output: tomorrow's date reldate yesterday # Output: yesterday's date reldate friday # Output: next Friday reldate fri # Output: next Friday reldate weekend # Output: next Saturday Adjustments: d = days, w = weeks, m = months, y = years Use + for future, - for past Keywords: today, tomorrow, yesterday monday-sunday (or mon-sun) weekend (Saturday) EOF exit 1 fi # Normalize input to lowercase input=$(echo "$1" | tr '[:upper:]' '[:lower:]') # Calculate days until a target weekday (1=Mon, 7=Sun) # Returns days to add (1-7, never 0 - same day means next week) days_until_weekday() { local target=$1 local current=$(date +%u) local diff=$(( (target - current + 7) % 7 )) if [[ $diff -eq 0 ]]; then diff=7 fi echo $diff } # Map day name to number (1=Mon, 7=Sun) day_to_number() { case "$1" in mon|monday) echo 1 ;; tue|tuesday) echo 2 ;; wed|wednesday) echo 3 ;; thu|thursday) echo 4 ;; fri|friday) echo 5 ;; sat|saturday) echo 6 ;; sun|sunday) echo 7 ;; *) echo 0 ;; esac } # Handle natural language keywords case "$input" in today) date "+%Y-%m-%d" ;; tomorrow) date -v "+1d" "+%Y-%m-%d" ;; yesterday) date -v "-1d" "+%Y-%m-%d" ;; weekend) days=$(days_until_weekday 6) date -v "+${days}d" "+%Y-%m-%d" ;; mon|monday|tue|tuesday|wed|wednesday|thu|thursday|fri|friday|sat|saturday|sun|sunday) day_num=$(day_to_number "$input") days=$(days_until_weekday "$day_num") date -v "+${days}d" "+%Y-%m-%d" ;; *) # Fall through to original logic if [[ "$1" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then date -j -f "%Y-%m-%d" "$1" "+%Y-%m-%d" 2>/dev/null || echo "Invalid date: $1" else date -v "$1" "+%Y-%m-%d" fi ;; esac