From d1850b17e797f1d9b9a06de5f28b4fbe25b32f33 Mon Sep 17 00:00:00 2001 From: favonia Date: Wed, 10 Jul 2024 12:17:33 +0300 Subject: [PATCH] feat(cron): show dates when needed (#795) --- cmd/ddns/ddns.go | 3 ++- internal/cron/countdown.go | 20 +++++++++++++--- internal/cron/countdown_test.go | 41 ++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/cmd/ddns/ddns.go b/cmd/ddns/ddns.go index 4e5123f4..b898fb46 100644 --- a/cmd/ddns/ddns.go +++ b/cmd/ddns/ddns.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "os" + "time" "github.com/favonia/cloudflare-ddns/internal/config" "github.com/favonia/cloudflare-ddns/internal/cron" @@ -161,7 +162,7 @@ func realMain() int { //nolint:funlen } // Display the remaining time interval - cron.PrintCountdown(ppfmt, "Checking the IP addresses", next) + cron.PrintCountdown(ppfmt, "Checking the IP addresses", time.Now(), next) // Wait for the next signal or the alarm, whichever comes first if !sig.SleepUntil(ppfmt, next) { diff --git a/internal/cron/countdown.go b/internal/cron/countdown.go index 109cebbe..f717cc80 100644 --- a/internal/cron/countdown.go +++ b/internal/cron/countdown.go @@ -12,8 +12,22 @@ const ( intervalHugeGap time.Duration = time.Minute * 10 ) -func PrintCountdown(ppfmt pp.PP, activity string, target time.Time) { - interval := time.Until(target) +func DescribeIntuitively(now, target time.Time) string { + now = now.In(time.Local) + target = target.In(time.Local) + + switch { + case now.Year() != target.Year(): + return target.In(time.Local).Format("02 Jan 15:04 2006") + case now.YearDay() != target.YearDay(): + return target.In(time.Local).Format("02 Jan 15:04") + default: + return target.In(time.Local).Format("15:04") + } +} + +func PrintCountdown(ppfmt pp.PP, activity string, now, target time.Time) { + interval := target.Sub(now) switch { case interval < -intervalLargeGap: @@ -28,7 +42,7 @@ func PrintCountdown(ppfmt pp.PP, activity string, target time.Time) { ppfmt.Infof(pp.EmojiAlarm, "%s in about %v (%v) . . .", activity, interval.Round(intervalUnit), - target.In(time.Local).Format(time.Kitchen), + DescribeIntuitively(now, target), ) } } diff --git a/internal/cron/countdown_test.go b/internal/cron/countdown_test.go index f6a0c903..92ceb282 100644 --- a/internal/cron/countdown_test.go +++ b/internal/cron/countdown_test.go @@ -11,6 +11,40 @@ import ( "github.com/favonia/cloudflare-ddns/internal/pp" ) +func TestDescribeIntuitively(t *testing.T) { + t.Parallel() + + now := time.Now().In(time.Local) + nextYear := now.AddDate(1, 0, 0) + diffDay := now.AddDate(0, 0, 1) + if diffDay.Year() != now.Year() { + diffDay = now.AddDate(0, 0, -1) + } + + for name, tc := range map[string]struct { + time time.Time + output string + }{ + "now": { + now, + now.Format("15:04"), + }, + "1day": { + diffDay, + diffDay.Format("02 Jan 15:04"), + }, + "1year": { + nextYear, + nextYear.Format("02 Jan 15:04 2006"), + }, + } { + t.Run(name, func(t *testing.T) { + t.Parallel() + require.Equal(t, tc.output, cron.DescribeIntuitively(now, tc.time)) + }) + } +} + func TestPrintCountdown(t *testing.T) { t.Parallel() @@ -69,9 +103,10 @@ func TestPrintCountdown(t *testing.T) { var buf strings.Builder pp := pp.New(&buf) - target := time.Now().Add(interval) - cron.PrintCountdown(pp, activity, target) - require.Equal(t, tc.output(target.Format(time.Kitchen)), buf.String()) + now := time.Now() + target := now.Add(interval) + cron.PrintCountdown(pp, activity, now, target) + require.Equal(t, tc.output(cron.DescribeIntuitively(now, target)), buf.String()) }) } }