From 4578eb24064fbef7a6f170418f2ef415927fd845 Mon Sep 17 00:00:00 2001 From: ruinivist Date: Tue, 10 Feb 2026 22:53:00 +0000 Subject: [PATCH] feat: add --time mode for using 24h time format --- cmd/tz-snipe/main.go | 19 ++++++++++++++----- internal/core/time.go | 33 +++++++++++++++++++++++++++++++++ internal/ui/model.go | 19 ++++++++++++++++++- 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 internal/core/time.go diff --git a/cmd/tz-snipe/main.go b/cmd/tz-snipe/main.go index b1ab1c6..fe2e7d1 100644 --- a/cmd/tz-snipe/main.go +++ b/cmd/tz-snipe/main.go @@ -18,6 +18,8 @@ func main() { tzFlag := flag.String("tz", "", "Timezone like +1000") // --github mode ghFlag := flag.String("github", "", "From a github username") + // --time mode + timeFlag := flag.String("time", "", "Time like 15:00") flag.Parse() @@ -29,17 +31,24 @@ func main() { } // 3. checks - if *tzFlag != "" && *ghFlag != "" { - fmt.Println("Cannot use both --tz and --github modes") + modes := 0 + for _, val := range []string{*tzFlag, *ghFlag, *timeFlag} { + if val != "" { + modes++ + } + } + + if modes > 1 { + fmt.Println("Cannot use multiple modes at once") os.Exit(1) } - if *tzFlag == "" && *ghFlag == "" { - fmt.Println("Both args empty... exiting") + if modes == 0 { + fmt.Println("No args provided... exiting") os.Exit(1) } // 4. exec - p := tea.NewProgram(ui.NewModel(db, *ghFlag, *tzFlag)) + p := tea.NewProgram(ui.NewModel(db, *ghFlag, *tzFlag, *timeFlag)) if _, err := p.Run(); err != nil { // I keep on forgetting, fmt.ErrorF makes an error, does not print fmt.Printf("Error: %v", err) diff --git a/internal/core/time.go b/internal/core/time.go new file mode 100644 index 0000000..e305e5f --- /dev/null +++ b/internal/core/time.go @@ -0,0 +1,33 @@ +package core + +import ( + "time" + "tz-snipe/internal/geodata" +) + +func GetTZsMatchingTime(db geodata.TimezoneMap, targetTime string) ([]string, error) { + // another go quirK: for layout it uses a fixed point in time + // as reference date Mon, 1/2 03:04:05 PM 2006 -0700 + // 1 2 3 4 5 6 7 + if _, err := time.Parse("15:04", targetTime); err != nil { + return nil, err + } + + now := time.Now().UTC() + var matches []string + + for tz := range db { + // Parse offset to location + zoneTime, err := time.Parse("-0700", tz) + if err != nil { + continue + } + + // Check if the formatted string matches exactly + // same minute match + if now.In(zoneTime.Location()).Format("15:04") == targetTime { + matches = append(matches, tz) + } + } + return matches, nil +} diff --git a/internal/ui/model.go b/internal/ui/model.go index db845c0..0b52430 100644 --- a/internal/ui/model.go +++ b/internal/ui/model.go @@ -29,7 +29,7 @@ var _ tea.Model = Model{} // REMINDER REMINDER REMINDER // Model, NewModel, Init, Commands, Update, View is all you need -func NewModel(db geodata.TimezoneMap, ghUser, manualTz string) Model { +func NewModel(db geodata.TimezoneMap, ghUser, manualTz, targetTime string) Model { m := Model{ db: db, username: ghUser, @@ -46,6 +46,23 @@ func NewModel(db geodata.TimezoneMap, ghUser, manualTz string) Model { m.table = newTable(m.preds) m.displayTz = m.manualTz } + case targetTime != "": + // Logic for time matching + tzs, err := core.GetTZsMatchingTime(db, targetTime) + if err != nil { + m.err = err + } else if len(tzs) == 0 { + m.err = fmt.Errorf("no timezones found matching %s", targetTime) + } else { + preds, err := core.GetStatsForTZs(tzs) + if err != nil { + m.err = err + } else { + m.preds = preds + m.table = newTable(m.preds) + m.displayTz = targetTime + } + } case ghUser != "": m.loadingGithubTz = true }