@@ -13,6 +13,7 @@ import (
1313 "github.com/charmbracelet/lipgloss/v2"
1414 "github.com/charmbracelet/lipgloss/v2/table"
1515 "github.com/spf13/cobra"
16+ "github.com/spf13/viper"
1617
1718 "github.com/DanStough/epok/internal/styles"
1819 "github.com/DanStough/epok/parse"
@@ -35,7 +36,11 @@ other formats. It can handle timestamps in various precisions and formats.`,
3536epok parse 1751074598
3637
3738# Read from stdin
38- pbpaste | epoch parse` ,
39+ pbpaste | epoch parse
40+
41+ # Override displayed timezones
42+ epok parse 1751074598 -z Big\ Ben=Europe/London,Tokyo\ SkyTree=Asia/Tokyo,Empire\ State=America/New_York
43+ ` ,
3944
4045 Args : cobra .MaximumNArgs (1 ),
4146
@@ -48,6 +53,14 @@ pbpaste | epoch parse`,
4853 SilenceUsage : true ,
4954 }
5055
56+ defaultLocales := map [string ]string {
57+ "Local" : "Local" ,
58+ "UTC" : "UTC" ,
59+ }
60+
61+ parseCmd .Flags ().StringToStringP ("timezone" , "z" , defaultLocales ,
62+ "override the map of locales:timezones. " +
63+ "Use 'Local' for system time." )
5164 return parseCmd
5265}
5366
@@ -63,30 +76,39 @@ func runParse(cmd *cobra.Command, args []string) error {
6376 input = args [0 ]
6477 }
6578
66- input = strings .TrimSpace (input )
67- timestamp , err := parse .String (input )
79+ mode , err := getOutput ()
6880 if err != nil {
69- return fmt . Errorf ( "could not parse input: %w" , err )
81+ return err
7082 }
7183
72- // TODO: consider having this load from a config
73- locales := map [string ]* time.Location {
74- "Local" : time .Local ,
75- "UTC" : time .UTC ,
84+ timezones := viper .GetStringMapString ("timezone" )
85+ if len (timezones ) == 0 {
86+ return errors .New ("must specify at least one locale timezone" )
7687 }
7788
78- out := newParseOutput (input , timestamp , locales )
79- mode , err := getOutput ()
89+ locales := make (map [string ]* time.Location , len (timezones ))
90+ for name , timezone := range timezones {
91+ loc , err := time .LoadLocation (timezone )
92+ if err != nil {
93+ return fmt .Errorf ("invalid timezone %s for locale %s: %w" , timezone , name , err )
94+ }
95+ locales [name ] = loc
96+ }
97+
98+ input = strings .TrimSpace (input )
99+ timestamp , err := parse .String (input )
80100 if err != nil {
81- return err
101+ return fmt . Errorf ( "could not parse input: %w" , err )
82102 }
83103
104+ out := newParseOutput (input , timestamp , locales )
105+
84106 switch mode {
85- case outputPretty :
107+ case outputModePretty :
86108 return out .writePretty (cmd .OutOrStdout ())
87- case outputSimple :
109+ case outputModeSimple :
88110 return out .writeSimple (cmd .OutOrStdout ())
89- case outputJson :
111+ case outputModeJson :
90112 return out .writeJson (cmd .OutOrStdout ())
91113 default :
92114 return fmt .Errorf ("unexpected output format: %s" , mode )
@@ -208,10 +230,16 @@ func (o *parseOutput) writePretty(w io.Writer) error {
208230 style = sheet .Table .OddRow
209231 }
210232
211- // TODO (dans): these need to change if we make the timezones configurable
233+ localeWidth := 8
234+ for _ , locale := range o .Locales {
235+ if len (locale .Name ) > localeWidth {
236+ localeWidth = len (locale .Name )
237+ }
238+ }
239+
212240 switch col {
213241 case 0 :
214- style = style .Width (8 )
242+ style = style .Width (localeWidth + 2 ) // include padding
215243 case 1 :
216244 style = style .Width (32 )
217245 case 2 :
0 commit comments