You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
2.4 KiB
140 lines
2.4 KiB
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
|
|
}
|