diff --git a/routes/summary.go b/routes/summary.go index f45e34c..f3084d2 100644 --- a/routes/summary.go +++ b/routes/summary.go @@ -9,6 +9,13 @@ import ( "github.com/n1try/wakapi/utils" ) +const ( + IntervalLastDay string = "day" + IntervalLastWeek string = "week" + IntervalLastMonth string = "month" + IntervalLastYear string = "year" +) + type SummaryHandler struct { SummarySrvc *services.SummaryService } @@ -23,15 +30,24 @@ func (h *SummaryHandler) Get(w http.ResponseWriter, r *http.Request) { params := r.URL.Query() from, err := utils.ParseDate(params.Get("from")) if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("Missing 'from' parameter")) - return + interval := params.Get("interval") + switch interval { + case IntervalLastDay: + from = utils.StartOfDay().Add(-24 * time.Hour) + case IntervalLastWeek: + from = utils.StartOfWeek() + case IntervalLastMonth: + from = utils.StartOfMonth() + case IntervalLastYear: + from = utils.StartOfYear() + default: + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Missing 'from' parameter")) + return + } } - now := time.Now() - to := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) // Start of current day - - summary, err := h.SummarySrvc.GetSummary(from, to, user) + summary, err := h.SummarySrvc.GetSummary(from, utils.StartOfDay(), user) if err != nil { w.WriteHeader(http.StatusInternalServerError) return diff --git a/utils/date.go b/utils/date.go new file mode 100644 index 0000000..7709ba5 --- /dev/null +++ b/utils/date.go @@ -0,0 +1,42 @@ +package utils + +import "time" + +func StartOfDay() time.Time { + ref := time.Now() + return time.Date(ref.Year(), ref.Month(), ref.Day(), 0, 0, 0, 0, ref.Location()) +} + +func StartOfWeek() time.Time { + ref := time.Now() + return firstDayOfISOWeek(ref.Year(), ref.Day(), ref.Location()) +} + +func StartOfMonth() time.Time { + ref := time.Now() + return time.Date(ref.Year(), ref.Month(), 0, 0, 0, 0, 0, ref.Location()) +} + +func StartOfYear() time.Time { + ref := time.Now() + return time.Date(ref.Year(), 0, 0, 0, 0, 0, 0, ref.Location()) +} + +// https://stackoverflow.com/a/18632496 +func firstDayOfISOWeek(year int, week int, timezone *time.Location) time.Time { + date := time.Date(year, 0, 0, 0, 0, 0, 0, timezone) + isoYear, isoWeek := date.ISOWeek() + for date.Weekday() != time.Monday { // iterate back to Monday + date = date.AddDate(0, 0, -1) + isoYear, isoWeek = date.ISOWeek() + } + for isoYear < year { // iterate forward to the first day of the first week + date = date.AddDate(0, 0, 1) + isoYear, isoWeek = date.ISOWeek() + } + for isoWeek < week { // iterate forward to the first day of the given week + date = date.AddDate(0, 0, 1) + isoYear, isoWeek = date.ISOWeek() + } + return date +}