From 6a588aaa9cf90e76e57a3af326e3dc6734dfd1ba Mon Sep 17 00:00:00 2001 From: lew Date: Thu, 2 Apr 2026 20:13:53 +0100 Subject: [PATCH] feat: consistent date formatting, year display, and iso/epoch time flags --- nag | 59 ++++++++++++++++++++++++++++++++++++++------------ test/list.bats | 41 ++++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/nag b/nag index 71f15aa..ba7ba3f 100755 --- a/nag +++ b/nag @@ -335,6 +335,8 @@ _SUBCOMMAND="" _SUBCOMMAND_ARGUMENTS=() _USE_DEBUG=0 _YES=0 +_RAW_TIME=0 +_EPOCH_TIME=0 while ((${#})) do @@ -356,6 +358,12 @@ do -f) _YES=1 ;; + --iso) + _RAW_TIME=1 + ;; + --epoch) + _EPOCH_TIME=1 + ;; *) # The first non-option argument is assumed to be the subcommand name. # All subsequent arguments are added to $_SUBCOMMAND_ARGUMENTS. @@ -754,9 +762,8 @@ _get_snooze_display() { local _expiry="${_entry#*$'\t'}" if (( _expiry > _now )) then - local _until_date - _until_date="$(date -d "@${_expiry}" "+%b %-d")" - REPLY=" (snoozed until ${_until_date})" + _format_time "${_expiry}" + REPLY=" (snoozed until ${REPLY})" fi else REPLY=" (snoozed)" @@ -879,6 +886,18 @@ _tag_list() { _format_time() { local _timestamp="${1}" + if (( _EPOCH_TIME )) + then + REPLY="${_timestamp}" + return + fi + + if (( _RAW_TIME )) + then + REPLY="$(date -d "@${_timestamp}" "+%Y-%m-%d %H:%M:%S")" + return + fi + # Single date call to get all needed components. local _date_parts _date_parts="$(date -d "@${_timestamp}" "+%-I|%M|%p|%Y-%m-%d|%A|%a %b %-d")" @@ -929,12 +948,21 @@ _format_time() { _date_prefix="Tomorrow" elif (( _days_away <= 6 )) then - _date_prefix="This ${_day_name}" + _date_prefix="${_day_name}" elif (( _days_away <= 13 )) then _date_prefix="Next ${_day_name}" else - _date_prefix="${_short_date}" + local _alarm_year + _alarm_year="$(date -d "${_alarm_date}" +%Y)" + local _this_year + _this_year="$(date +%Y)" + if [[ "${_alarm_year}" != "${_this_year}" ]] + then + _date_prefix="${_short_date} ${_alarm_year}" + else + _date_prefix="${_short_date}" + fi fi REPLY="${_date_prefix}, ${_time_fmt}" @@ -1470,7 +1498,7 @@ Usage: ${_ME} tag add tags to an alarm ${_ME} tag list alarms with a tag ${_ME} untag remove tags from an alarm - ${_ME} snooze [] snooze alarms + ${_ME} snooze [] snooze alarms ${_ME} unsnooze unsnooze alarms ${_ME} check check and fire due alarms ${_ME} mute mute alarm sounds @@ -1480,9 +1508,11 @@ Usage: ${_ME} version show version Options: - -e Edit alarms file directly. - -f Skip all prompts. - -v Show version. + -e Edit alarms file directly. + -f Skip all prompts. + --iso Show times as YYYY-MM-DD HH:MM:SS. + --epoch Show times as unix timestamps. + -v Show version. Environment: NAG_DIR Alarm storage directory (default: ~/.local/share/nag) @@ -2459,7 +2489,8 @@ _snooze_by_tag() { if [[ -n "${_duration_str}" ]] then _until_ts="$(_parse_time "${_duration_str}")" - _until_date="$(date -d "@${_until_ts}" "+%b %-d")" + _format_time "${_until_ts}" + _until_date="${REPLY}" fi for _line in "${_ALARMS[@]}" @@ -2506,7 +2537,8 @@ snooze() { if [[ -n "${_duration_str}" ]] then _until_ts="$(_parse_time "${_duration_str}")" - _until_date="$(date -d "@${_until_ts}" "+%b %-d")" + _format_time "${_until_ts}" + _until_date="${REPLY}" fi local _line @@ -2570,9 +2602,8 @@ snooze() { _until_ts="$(_parse_time "${_duration_str}")" printf "%s\t%s\\n" "${_target}" "${_until_ts}" >> "${_SNOOZED_FILE}" _release_lock - local _until_date - _until_date="$(date -d "@${_until_ts}" "+%b %-d")" - printf "Snoozed [%s] %s until %s.\\n" "${_target}" "${_message}" "${_until_date}" + _format_time "${_until_ts}" + printf "Snoozed [%s] %s until %s.\\n" "${_target}" "${_message}" "${REPLY}" else printf "%s\\n" "${_target}" >> "${_SNOOZED_FILE}" _release_lock diff --git a/test/list.bats b/test/list.bats index 7d52379..7eeb010 100644 --- a/test/list.bats +++ b/test/list.bats @@ -84,13 +84,13 @@ load test_helper [[ "${output}" =~ "Tomorrow,".*"tomorrow alarm" ]] } -@test "list shows This for alarm 3 days away" { +@test "list shows for alarm 3 days away" { local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 3 + 43200 )) local _day="$(date -d "@${_ts}" +%A)" write_alarm "$(printf '1\t\t%s\t\tthis alarm' "${_ts}")" run_nag [ "${status}" -eq 0 ] - [[ "${output}" =~ "This ${_day},".*"this alarm" ]] + [[ "${output}" =~ "${_day},".*"this alarm" ]] } @test "list shows Next for alarm 10 days away" { @@ -124,11 +124,22 @@ load test_helper run_nag at "tomorrow 3pm" "take a break" local _expiry_ts=$(( $(date +%s) + 86400 * 7 )) printf "1\t%s\\n" "${_expiry_ts}" > "${NAG_DIR}/snoozed" - local _expiry_date - _expiry_date="$(date -d "@${_expiry_ts}" "+%b %-d")" run_nag [ "${status}" -eq 0 ] - [[ "${output}" =~ "snoozed until ${_expiry_date}" ]] + # Should use the same format as list dates (e.g. "Next Monday, 3pm"). + [[ "${output}" =~ "snoozed until " ]] + [[ "${output}" =~ "am)" ]] || [[ "${output}" =~ "pm)" ]] +} + +@test "list shows year for alarm in a different year" { + local _next_year=$(( $(date +%Y) + 1 )) + local _ts + _ts="$(date -d "${_next_year}-06-15 14:00:00" +%s)" + write_alarm "$(printf '1\t\t%s\t\tnext year alarm' "${_ts}")" + run_nag + [ "${status}" -eq 0 ] + [[ "${output}" =~ "${_next_year}" ]] + [[ "${output}" =~ "next year alarm" ]] } @test "list does not show (snoozed) for unsnoozed alarm" { @@ -137,3 +148,23 @@ load test_helper [ "${status}" -eq 0 ] [[ ! "${output}" =~ "snoozed" ]] } + +@test "--iso flag shows YYYY-MM-DD HH:MM:SS format" { + local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 + 54000 )) + write_alarm "$(printf '1\t\t%s\t\traw alarm' "${_ts}")" + local _expected + _expected="$(date -d "@${_ts}" "+%Y-%m-%d %H:%M:%S")" + run "${_NAG}" -f --iso + [ "${status}" -eq 0 ] + [[ "${output}" =~ "${_expected}" ]] + [[ "${output}" =~ "raw alarm" ]] +} + +@test "--epoch flag shows unix timestamps" { + local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 + 54000 )) + write_alarm "$(printf '1\t\t%s\t\tepoch alarm' "${_ts}")" + run "${_NAG}" -f --epoch + [ "${status}" -eq 0 ] + [[ "${output}" =~ "${_ts}" ]] + [[ "${output}" =~ "epoch alarm" ]] +}