Skip to content

Commit c12ae79

Browse files
committed
feat: Add flag to set the timezone on reports
By default all the dates are in UTC, this commit adds a new flag: '--time-zone' or '-z' that allows the user to pass a timezone. This is a breaking change, now, by default the used timezone is 'local', meaning the value returned by 'time.local'. Examples: - Madrid Timezone: -z Europe/Madrid - Current timezone: -z local A full list of timezones can be found here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones This can fix some issues reported in #135. Signed-off-by: Arturo Volpe <[email protected]>
1 parent ae51973 commit c12ae79

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

pkg/cmd/time-entry/report/util/report.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (rf ReportFlags) Check() error {
5050
// NewReportFlags helps creating a util.ReportFlags for report commands
5151
func NewReportFlags() ReportFlags {
5252
return ReportFlags{
53-
OutputFlags: util.OutputFlags{TimeFormat: timehlp.FullTimeFormat},
53+
OutputFlags: util.OutputFlags{TimeFormat: timehlp.FullTimeFormat, TimeZone: "local"},
5454
}
5555
}
5656

pkg/cmd/time-entry/report/util/reportwithrange_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ func TestReportWithRange(t *testing.T) {
246246
},
247247
flags: func(t *testing.T) util.ReportFlags {
248248
rf := util.NewReportFlags()
249+
rf.TimeZone = "UTC"
249250
rf.FillMissingDates = true
250251
rf.Format = "{{.ID}};{{ .TimeInterval.Start.Format " +
251252
`"2006-01-02"` +

pkg/cmd/time-entry/util/report.go

+44-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package util
22

33
import (
44
"io"
5+
"time"
56

67
"github.com/lucassabreu/clockify-cli/api"
78
"github.com/lucassabreu/clockify-cli/api/dto"
@@ -19,20 +20,29 @@ type OutputFlags struct {
1920
Markdown bool
2021
DurationFormatted bool
2122
DurationFloat bool
22-
23-
TimeFormat string
23+
TimeFormat string
24+
TimeZone string
2425
}
2526

2627
func (of OutputFlags) Check() error {
27-
return cmdutil.XorFlag(map[string]bool{
28+
29+
if err := cmdutil.XorFlag(map[string]bool{
2830
"format": of.Format != "",
2931
"json": of.JSON,
3032
"csv": of.CSV,
3133
"quiet": of.Quiet,
3234
"md": of.Markdown,
3335
"duration-float": of.DurationFloat,
3436
"duration-formatted": of.DurationFormatted,
35-
})
37+
}); err != nil {
38+
return err
39+
}
40+
41+
if of.TimeZone != "local" && of.TimeFormat != "" {
42+
_, err := time.LoadLocation(of.TimeZone)
43+
return err
44+
}
45+
return nil
3646
}
3747

3848
// AddPrintMultipleTimeEntriesFlags add flags to print multiple time entries
@@ -45,6 +55,8 @@ func AddPrintMultipleTimeEntriesFlags(cmd *cobra.Command) {
4555
func AddPrintTimeEntriesFlags(cmd *cobra.Command, of *OutputFlags) {
4656
cmd.Flags().StringVarP(&of.Format, "format", "f", "",
4757
"golang text/template format to be applied on each time entry")
58+
cmd.Flags().StringVarP(&of.TimeZone, "time-zone", "z", "local",
59+
"time zone to be used on the time entries")
4860
cmd.Flags().BoolVarP(&of.JSON, "json", "j", false, "print as JSON")
4961
cmd.Flags().BoolVarP(&of.CSV, "csv", "v", false, "print as CSV")
5062
cmd.Flags().BoolVarP(&of.Quiet, "quiet", "q", false, "print only ID")
@@ -91,18 +103,45 @@ func PrintTimeEntry(
91103
b := config.GetBool(cmdutil.CONF_SHOW_TOTAL_DURATION)
92104
config.SetBool(cmdutil.CONF_SHOW_TOTAL_DURATION, false)
93105

94-
err := PrintTimeEntries(ts, out, config, of)
106+
err := PrintTimeEntries(updateTimeZone(ts, of), out, config, of)
95107

96108
config.SetBool(cmdutil.CONF_SHOW_TOTAL_DURATION, b)
97109

98110
return err
99111
}
100112

113+
func updateTimeZone(tes []dto.TimeEntry, of OutputFlags) []dto.TimeEntry {
114+
115+
if of.TimeZone == "" {
116+
return tes
117+
}
118+
119+
var loc *time.Location = time.UTC
120+
121+
if of.TimeZone == "local" || of.TimeFormat == "" {
122+
loc = time.Local
123+
} else {
124+
loc, _ = time.LoadLocation(of.TimeZone)
125+
}
126+
127+
// iterate tes and set the end/start time to the timezone
128+
for i := range tes {
129+
// parses of.TimeZone as a time.Location
130+
tes[i].TimeInterval.Start = tes[i].TimeInterval.Start.In(loc)
131+
if tes[i].TimeInterval.End != nil {
132+
end := tes[i].TimeInterval.End.In(loc)
133+
tes[i].TimeInterval.End = &end
134+
}
135+
}
136+
return tes
137+
}
138+
101139
// PrintTimeEntries will print out a list of time entries using parameters and
102140
// flags
103141
func PrintTimeEntries(
104142
tes []dto.TimeEntry, out io.Writer, config cmdutil.Config, of OutputFlags,
105143
) error {
144+
tes = updateTimeZone(tes, of)
106145
switch {
107146
case of.Markdown:
108147
return output.TimeEntriesMarkdownPrint(tes, out)

0 commit comments

Comments
 (0)