package aid import ( "errors" "time" ) func TimeStartOfDay() string { return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()).Format("2006-01-02T15:04:05.999Z") } func TimeEndOfDay() string { return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 999999999, time.Now().Location()).Format("2006-01-02T15:04:05.999Z") } func TimeEndOfWeekString() string { return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 999999999, time.Now().Location()).AddDate(0, 0, 7).Format("2006-01-02T15:04:05.999Z") } // everything below is taken from the golang standard library I just added the extra units to the map var unitMap = map[string]uint64{ "ns": uint64(time.Nanosecond), "us": uint64(time.Microsecond), "µs": uint64(time.Microsecond), // U+00B5 = micro symbol "μs": uint64(time.Microsecond), // U+03BC = Greek letter mu "ms": uint64(time.Millisecond), "s": uint64(time.Second), "m": uint64(time.Minute), "h": uint64(time.Hour), "d": uint64(time.Hour * 24), "w": uint64(time.Hour * 24 * 7), "y": uint64(time.Hour * 24 * 365), // no leap year "c": uint64(time.Hour * 24 * 365 * 100), // no leap year } // ParseDuration parses a duration string. // A duration string is a possibly signed sequence of // decimal numbers, each with optional fraction and a unit suffix, // such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". func leadingFraction(s string) (x uint64, scale float64, rem string) { i := 0 scale = 1 overflow := false for ; i < len(s); i++ { c := s[i] if c < '0' || c > '9' { break } if overflow { continue } if x > (1<<63-1)/10 { // It's possible for overflow to give a positive number, so take care. overflow = true continue } y := x*10 + uint64(c) - '0' if y > 1<<63 { overflow = true continue } x = y scale *= 10 } return x, scale, s[i:] } func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) { i := 0 for ; i < len(s); i++ { c := s[i] if c < '0' || c > '9' { break } if x > 1<<63/10 { // overflow return 0, rem, errors.New("time: invalid duration ") } x = x*10 + uint64(c) - '0' if x > 1<<63 { // overflow return 0, rem, errors.New("time: invalid duration ") } } return x, s[i:], nil } func ParseDuration(s string) (time.Duration, error) { // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+ var d uint64 neg := false // Consume [-+]? if s != "" { c := s[0] if c == '-' || c == '+' { neg = c == '-' s = s[1:] } } // Special case: if all that is left is "0", this is zero. if s == "0" { return 0, nil } if s == "" { return 0, errors.New("time: invalid duration") } for s != "" { var ( v, f uint64 // integers before, after decimal point scale float64 = 1 // value = v + f/scale ) var err error // The next character must be [0-9.] if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') { return 0, errors.New("time: invalid duration") } // Consume [0-9]* pl := len(s) v, s, err = leadingInt(s) if err != nil { return 0, errors.New("time: invalid duration") } pre := pl != len(s) // whether we consumed anything before a period // Consume (\.[0-9]*)? post := false if s != "" && s[0] == '.' { s = s[1:] pl := len(s) f, scale, s = leadingFraction(s) post = pl != len(s) } if !pre && !post { // no digits (e.g. ".s" or "-.s") return 0, errors.New("time: invalid duration") } // Consume unit. i := 0 for ; i < len(s); i++ { c := s[i] if c == '.' || '0' <= c && c <= '9' { break } } if i == 0 { return 0, errors.New("time: missing unit in duration") } u := s[:i] s = s[i:] unit, ok := unitMap[u] if !ok { return 0, errors.New("time: unknown unit in duration") } if v > 1<<63/unit { // overflow return 0, errors.New("time: invalid duration ") } v *= unit if f > 0 { // float64 is needed to be nanosecond accurate for fractions of hours. // v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit) v += uint64(float64(f) * (float64(unit) / scale)) if v > 1<<63 { // overflow return 0, errors.New("time: invalid duration") } } d += v if d > 1<<63 { return 0, errors.New("time: invalid duration") } } if neg { return -time.Duration(d), nil } if d > 1<<63-1 { return 0, errors.New("time: invalid duration") } return time.Duration(d), nil }