|
|
package models
import ( "bytes" "encoding/json" "fmt" "strconv" "strings" "time" )
var TimeOfDayTimeZone = time.UTC
type TimeOfDay int
func (t *TimeOfDay) UnmarshalJSON(v []byte) error { if bytes.Equal(v, []byte("null")) { *t = -1 }
var str string err := json.Unmarshal(v, &str) if err != nil { var n int err = json.Unmarshal(v, &n) if err != nil { return err } if n < -1 && n >= 86400 { return fmt.Errorf("value outside range 0..86400: %d", n) } }
t2, err := ParseTimeOfDay(str) if err != nil { return err }
*t = t2
return nil }
func (t TimeOfDay) MarshalJSON() ([]byte, error) { if t.IsNever() { return []byte("null"), nil }
return json.Marshal(t.String()) }
const Never = TimeOfDay(-1)
func (t *TimeOfDay) String() string { if *t < 0 { return "n/a" }
return fmt.Sprintf("%02d:%02d:%02d", *t/3600, (*t/60)%60, *t%60) }
func (t *TimeOfDay) StringPtr() *string { if *t < 0 { return nil }
s := t.String() return &s }
func (t TimeOfDay) IsNever() bool { return t == Never }
func (t TimeOfDay) IsBetween(from TimeOfDay, to TimeOfDay) bool { if from == to { return t == from } else if from > to { return t >= from || t <= to } else { return t >= from && t <= to } }
func CurrentTimeOfDay() TimeOfDay { return TimeOfDayFromDate(time.Now().In(TimeOfDayTimeZone)) }
func TimeOfDayFromDate(date time.Time) TimeOfDay { localDate := date.In(TimeOfDayTimeZone) return NewTimeOfDay(localDate.Hour(), localDate.Minute(), localDate.Second()) }
func NewTimeOfDay(hours, minutes, seconds int) TimeOfDay { return TimeOfDay(((hours % 24) * 3600) + ((minutes % 60) * 60) + seconds) }
func ParseTimeOfDayPtr(str *string) (TimeOfDay, error) { if str == nil { return Never, nil }
return ParseTimeOfDay(*str) }
func ParseTimeOfDay(str string) (TimeOfDay, error) { if str == "" || str == "n/a" || str == "N/A" { return -1, nil }
split := strings.SplitN(str, ":", 4) res := 0
n, err := strconv.Atoi(split[0]) if err != nil { return Never, err } res += n * 3600
if len(split) >= 2 { n, err := strconv.Atoi(split[1]) if err != nil { return Never, err } res += n * 60 } if len(split) >= 3 { n, err := strconv.Atoi(split[2]) if err != nil { return Never, err } res += n }
if res >= 86400 || res < 0 { return Never, fmt.Errorf("invalid time of day string %s (=%d)", str, res) }
return TimeOfDay(res), nil }
|