#!/usr/bin/env bash # date_utils.sh - Date utility functions for exitrace # Maintainer: ljp # Constants readonly DATE_FMT="%Y-%m-%d" readonly MAX_DAYS_LIMIT=400 # Validation functions validate_positive_integer() { local value="$1" local param="$2" if [[ -z "$value" ]]; then echo "Fehler: Parameter $param benötigt einen Wert" >&2 exit 1 fi if ! [[ "$value" =~ ^[0-9]+$ ]]; then echo "Fehler: $param muss eine positive Zahl sein (gegeben: '$value')" >&2 exit 1 fi if [[ "$value" -eq 0 ]]; then echo "Fehler: $param muss größer als 0 sein" >&2 exit 1 fi } validate_date() { local date_val="$1" local param="$2" if [[ -z "$date_val" ]]; then echo "Fehler: Parameter $param benötigt einen Wert" >&2 exit 1 fi if ! date -d "$date_val" >/dev/null 2>&1; then echo "Fehler: Ungültiges Datumsformat für $param: '$date_val'" >&2 echo "Erwartetes Format: YYYY-MM-DD" >&2 exit 1 fi } validate_date_range() { local range="$1" if [[ -z "$range" ]]; then echo "Fehler: --range benötigt einen Wert" >&2 exit 1 fi if [[ "$range" != *".."* ]]; then echo "Fehler: Ungültiges Range-Format: '$range'" >&2 echo "Erwartetes Format: YYYY-MM-DD..YYYY-MM-DD" >&2 exit 1 fi local start_date="${range%%..*}" local end_date="${range##*..}" validate_date "$start_date" "--range Startdatum" validate_date "$end_date" "--range Enddatum" } # Date generation functions gen_dates_hours_back() { local hrs="$1" start_ts end_ts cur next_ts end_ts="$(date +%s)" || { echo "Fehler: Kann aktuellen Timestamp nicht ermitteln" >&2; exit 1; } start_ts="$(date -d "-${hrs} hours" +%s)" || { echo "Fehler: Kann Start-Timestamp nicht berechnen" >&2; exit 1; } cur="$(date -d "@$start_ts" +${DATE_FMT})" || { echo "Fehler: Kann Startdatum nicht formatieren" >&2; exit 1; } local iterations=0 while :; do echo "$cur" next_ts="$(date -d "$cur +1 day" +%s 2>/dev/null)" || { echo "Fehler: Datumsberechnung fehlgeschlagen für $cur" >&2; exit 1; } [[ "$next_ts" -le "$end_ts" ]] || break cur="$(date -d "$cur +1 day" +${DATE_FMT} 2>/dev/null)" || { echo "Fehler: Datum-Inkrement fehlgeschlagen für $cur" >&2; exit 1; } # Sicherheit gegen Endlosschleifen ((iterations++)) if [[ $iterations -gt $MAX_DAYS_LIMIT ]]; then echo "Fehler: Zu viele Tage im Zeitfenster (>$MAX_DAYS_LIMIT Tage)" >&2 exit 1 fi done } gen_dates_days_back() { local days="$1" i for ((i=0;i<=days;i++)); do date -d "-$i day" +${DATE_FMT} || { echo "Fehler: Kann Datum für -$i day nicht berechnen" >&2; exit 1; } done } gen_dates_range() { local a="${1%%..*}" b="${1##*..}" cur="$a" local iterations=0 while :; do echo "$cur" [[ "$cur" == "$b" ]] && break cur="$(date -d "$cur +1 day" +${DATE_FMT} 2>/dev/null)" || { echo "Fehler: Datum-Inkrement fehlgeschlagen für $cur" >&2; exit 1; } # Sicherheit gegen Endlosschleifen ((iterations++)) if [[ $iterations -gt $MAX_DAYS_LIMIT ]]; then echo "Fehler: Zu großer Datumsbereich (>$MAX_DAYS_LIMIT Tage)" >&2 exit 1 fi done } files_for_date() { local d="$1" y="${d:0:4}" m="${d:5:2}" local logroot="${LOGROOT:-/var/log/easyname}" local p="${logroot}/${y}/${m}/${d}.log" if [[ -f "$p" ]]; then printf "%s\n" "$p" fi if [[ -f "${p}.gz" ]]; then printf "%s\n" "${p}.gz" fi } # Built with the help of Claude Code