diff --git a/date_utils/date_utils.go b/date_utils/date_utils.go index edace1f239e17a5e2dbc175886dd3d56f843d201..3003c28c057ee773bda3cbdf02657b147f667a82 100644 --- a/date_utils/date_utils.go +++ b/date_utils/date_utils.go @@ -3,6 +3,7 @@ package date_utils import ( "reflect" "strconv" + "strings" "time" "github.com/araddon/dateparse" @@ -273,7 +274,139 @@ func formatTimestampsWithTimeZoneInSlice(fieldValue reflect.Value, location *tim return nil } -type TradingHours struct { - Days string `json:"days"` - Times string `json:"times"` +// TradingHours represents an array of (StartTime,EndTime) pairs, one for each day of the week. +// The array is 0 indexed, with 0 being Monday and 6 being Sunday. +type TradingHours [7]struct { + StartTime string `json:"start_time"` + EndTime string `json:"end_time"` +} + +func (t *TradingHours) Validate() bool { + if t == nil { + return false + } + + for _, day := range t { + if !TimeBefore(day.StartTime, day.EndTime) { + return false + } + + if len(day.StartTime) != 5 || len(day.EndTime) != 5 { + return false + } + + startHourMinSlice := strings.Split(day.StartTime, ":") + startHour, startMin := startHourMinSlice[0], startHourMinSlice[1] + startHourInt, err := strconv.Atoi(startHour) + if err != nil || startHourInt < 0 || startHourInt > 23 { + return false + } + startMinInt, err := strconv.Atoi(startMin) + if err != nil || !(startMinInt == 0 || startMinInt == 30) { + return false + } + + endHourMinSlice := strings.Split(day.EndTime, ":") + endHour, endMin := endHourMinSlice[0], endHourMinSlice[1] + endHourInt, err := strconv.Atoi(endHour) + if err != nil || endHourInt < 0 || endHourInt > 23 { + return false + } + endMinInt, err := strconv.Atoi(endMin) + if err != nil || !(endMinInt == 0 || endMinInt == 30 || endMinInt == 59) { + return false + } + } + + return true +} + +func (t *TradingHours) String() string { + var dayMap = map[int]string{ + 0: "Mon", + 1: "Tue", + 2: "Wed", + 3: "Thu", + 4: "Fri", + 5: "Sat", + 6: "Sun", + } + + var timeMap = map[string]string{ + "00:00": "12am", + "00:30": "12:30am", + "01:00": "1am", + "01:30": "1:30am", + "02:00": "2am", + "02:30": "2:30am", + "03:00": "3am", + "03:30": "3:30am", + "04:00": "4am", + "04:30": "4:30am", + "05:00": "5am", + "05:30": "5:30am", + "06:00": "6am", + "06:30": "6:30am", + "07:00": "7am", + "07:30": "7:30am", + "08:00": "8am", + "08:30": "8:30am", + "09:00": "9am", + "09:30": "9:30am", + "10:00": "10am", + "10:30": "10:30am", + "11:00": "11am", + "11:30": "11:30am", + "12:00": "12pm", + "12:30": "12:30pm", + "13:00": "1pm", + "13:30": "1:30pm", + "14:00": "2pm", + "14:30": "2:30pm", + "15:00": "3pm", + "15:30": "3:30pm", + "16:00": "4pm", + "16:30": "4:30pm", + "17:00": "5pm", + "17:30": "5:30pm", + "18:00": "6pm", + "18:30": "6:30pm", + "19:00": "7pm", + "19:30": "7:30pm", + "20:00": "8pm", + "20:30": "8:30pm", + "21:00": "9pm", + "21:30": "9:30pm", + "22:00": "10pm", + "22:30": "10:30pm", + "23:00": "11pm", + "23:30": "11:30pm", + "23:59": "11:59pm", + } + + result := "" + rangeStartIndex := 0 + for i := 0; i < len(t); i++ { + times := timeMap[t[i].StartTime] + "-" + timeMap[t[i].EndTime] + if t[i].StartTime == "00:00" && t[i].EndTime == "23:59" { + times = "All day" + } + + // If we're at the last element or the next day doesn't have the same times, we end the current range + if i == len(t)-1 || t[i].StartTime != t[i+1].StartTime || t[i].EndTime != t[i+1].EndTime { + if rangeStartIndex == i { + result += dayMap[i] + ": " + times + } else { + result += dayMap[rangeStartIndex] + "-" + dayMap[i] + ": " + times + } + + if i < len(t)-1 { + result += ", " + } + + rangeStartIndex++ + } + } + + return result }