diff --git a/date_utils/date_utils.go b/date_utils/date_utils.go index 68be30f42eb19c9446038911c492d6ed4c0fb913..c86bc6aca0db27500a6a4d8494dba274da17929d 100644 --- a/date_utils/date_utils.go +++ b/date_utils/date_utils.go @@ -277,15 +277,15 @@ func formatTimestampsWithTimeZoneInSlice(fieldValue reflect.Value, location *tim } // TradingHours represents an array of (StartTime,EndTime) pairs, one for each day of the week. -// The array is 0 indexed, with 0 being Sunday and 6 being Saturday. +// The array is 0 indexed, with 0 being Sunday and 6 being Saturday and 7 being public holidays. type TradingHours []struct { StartTime string `json:"start_time"` EndTime string `json:"end_time"` } func (t TradingHours) Validate() error { - if len(t) != 7 { - return errors.Error("Trading hours must have 7 days") + if len(t) != 8 { + return errors.Error("Trading hours must have 8 days, 7 for every day of the week and 1 for public holidays") } for _, day := range t { @@ -336,26 +336,33 @@ func (t TradingHours) Validate() error { func (t TradingHours) String() string { var result strings.Builder - t = append(t, t[0]) // Add the first day (Sunday) to the end because we want Monday to be first in the string const numberOfDaysInWeek = 7 + weekdays, publicHolidays := t[:numberOfDaysInWeek], t[numberOfDaysInWeek] + weekdays = append(weekdays, weekdays[0]) // Add the first day (Sunday) to the end because we want Monday to be first in the string rangeStartIndex := 1 - for i := 1; i < len(t); i++ { - var times string + for i := 1; i < len(weekdays); i++ { + currentDay := weekdays[i] + nextDay := currentDay + if i+1 < len(weekdays)-1 { + nextDay = weekdays[i+1] + } - if t[i].StartTime != "" && t[i].EndTime != "" { - startTime, err := time.Parse("15:04", t[i].StartTime) + // Determine times + var times string + if currentDay.StartTime != "" && currentDay.EndTime != "" { + startTime, err := time.Parse("15:04", currentDay.StartTime) if err != nil { return "" } - endTime, err := time.Parse("15:04", t[i].EndTime) + endTime, err := time.Parse("15:04", currentDay.EndTime) if err != nil { return "" } times = startTime.Format("3:04pm") + "-" + endTime.Format("3:04pm") - if t[i].StartTime == "00:00" && t[i].EndTime == "23:59" { + if currentDay.StartTime == "00:00" && currentDay.EndTime == "23:59" { times = "All day" } } else { @@ -363,7 +370,7 @@ func (t TradingHours) String() string { } // 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 i == len(weekdays)-1 || currentDay.StartTime != nextDay.StartTime || currentDay.EndTime != nextDay.EndTime { if rangeStartIndex == i { day := time.Weekday(rangeStartIndex).String() if rangeStartIndex == numberOfDaysInWeek { @@ -379,7 +386,7 @@ func (t TradingHours) String() string { result.WriteString(fmt.Sprintf("%s-%s: %s", rangeStartDay, rangeEndDay, times)) } - if i < len(t)-1 { + if i < len(weekdays)-1 { result.WriteString(", ") } @@ -387,5 +394,27 @@ func (t TradingHours) String() string { } } + // Public holidays + var times string + if publicHolidays.StartTime != "" && publicHolidays.EndTime != "" { + startTime, err := time.Parse("15:04", publicHolidays.StartTime) + if err != nil { + return "" + } + + endTime, err := time.Parse("15:04", publicHolidays.EndTime) + if err != nil { + return "" + } + + times = startTime.Format("3:04pm") + "-" + endTime.Format("3:04pm") + if publicHolidays.StartTime == "00:00" && publicHolidays.EndTime == "23:59" { + times = "All day" + } + } else { + times = "Closed" + } + result.WriteString(fmt.Sprintf(", Public Holidays: %s", times)) + return result.String() }