Skip to content
Snippets Groups Projects
Commit d8e1d9cf authored by Daniel Naude's avatar Daniel Naude
Browse files

Refactor TradingHours Validation and String functions

parent 59ba807c
No related branches found
No related tags found
No related merge requests found
package date_utils
import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
"github.com/araddon/dateparse"
"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors"
)
const TimeZoneString = "Africa/Johannesburg"
......@@ -275,125 +277,76 @@ 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 Monday and 6 being Sunday.
// The array is 0 indexed, with 0 being Sunday and 6 being Saturday.
type TradingHours []struct {
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
}
func (t TradingHours) Validate() bool {
if t == nil {
return false
func (t TradingHours) Validate() error {
if len(t) != 7 {
return errors.Error("Trading hours must have 7 days")
}
for _, day := range t {
if !TimeBefore(day.StartTime, day.EndTime) {
return false
return errors.Error("Start time must be before end time")
}
if len(day.StartTime) != 5 || len(day.EndTime) != 5 {
return false
return errors.Error("Time must be in the format HH:MM")
}
startHourMinSlice := strings.Split(day.StartTime, ":")
if len(startHourMinSlice) != 2 {
return false
return errors.Error("Time must be in the format HH:MM")
}
startHour, startMin := startHourMinSlice[0], startHourMinSlice[1]
startHourInt, err := strconv.Atoi(startHour)
if err != nil || startHourInt < 0 || startHourInt > 23 {
return false
return errors.Error("Start hour must be between 0 and 23")
}
startMinInt, err := strconv.Atoi(startMin)
if err != nil || !(startMinInt == 0 || startMinInt == 30) {
return false
return errors.Error("Start minute must be 0 or 30")
}
endHourMinSlice := strings.Split(day.EndTime, ":")
if len(endHourMinSlice) != 2 {
return false
return errors.Error("Time must be in the format HH:MM")
}
endHour, endMin := endHourMinSlice[0], endHourMinSlice[1]
endHourInt, err := strconv.Atoi(endHour)
if err != nil || endHourInt < 0 || endHourInt > 23 {
return false
return errors.Error("End hour must be between 0 and 23")
}
endMinInt, err := strconv.Atoi(endMin)
if err != nil || !(endMinInt == 0 || endMinInt == 30 || endMinInt == 59) {
return false
return errors.Error("End minute must be 0, 30 or 59")
}
}
return true
return nil
}
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]
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
rangeStartIndex := 1
for i := 1; i < len(t); i++ {
startTime, err := time.Parse("15:04", t[i].StartTime)
if err != nil {
return ""
}
endTime, err := time.Parse("15:04", t[i].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" {
times = "All day"
}
......@@ -401,18 +354,27 @@ 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 rangeStartIndex == i {
result += dayMap[i] + ": " + times
day := time.Weekday(rangeStartIndex).String()
if rangeStartIndex == numberOfDaysInWeek {
day = time.Sunday.String()
}
result.WriteString(fmt.Sprintf("%s: %s", day, times))
} else {
result += dayMap[rangeStartIndex] + "-" + dayMap[i] + ": " + times
rangeStartDay := time.Weekday(rangeStartIndex).String()
rangeEndDay := time.Weekday(i).String()
if i == numberOfDaysInWeek {
rangeEndDay = time.Sunday.String()
}
result.WriteString(fmt.Sprintf("%s-%s: %s", rangeStartDay, rangeEndDay, times))
}
if i < len(t)-1 {
result += ", "
result.WriteString(", ")
}
rangeStartIndex++
rangeStartIndex = i + 1
}
}
return result
return result.String()
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment