github.com/searKing/golang/go@v1.2.117/time/time.go (about) 1 // Copyright 2021 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package time 6 7 import ( 8 "encoding/json" 9 "time" 10 ) 11 12 // TruncateByLocation only happens in local semantics, apparently. 13 // observed values for truncating given time with 24 Hour: 14 // before truncation: 2012-01-01 04:15:30 +0800 CST 15 // after truncation: 2012-01-01 00:00:00 +0800 CST 16 // 17 // time.Truncate only happens in UTC semantics, apparently. 18 // observed values for truncating given time with 24 Hour: 19 // 20 // before truncation: 2012-01-01 04:15:30 +0800 CST 21 // after truncation: 2011-12-31 08:00:00 +0800 CST 22 // 23 // This is really annoying when we want to truncate in local time 24 // we take the apparent local time in the local zone, and pretend 25 // that it's in UTC. do our math, and put it back to the local zone 26 func TruncateByLocation(t time.Time, d time.Duration) time.Time { 27 if t.Location() == time.UTC { 28 return t.Truncate(d) 29 } 30 31 utc := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC) 32 utc = utc.Truncate(d) 33 return time.Date(utc.Year(), utc.Month(), utc.Day(), utc.Hour(), utc.Minute(), utc.Second(), utc.Nanosecond(), 34 t.Location()) 35 } 36 37 // Duration is alias of time.Duration for marshal and unmarshal 38 type Duration time.Duration 39 40 func (d Duration) MarshalJSON() ([]byte, error) { 41 return json.Marshal(time.Duration(d).String()) 42 } 43 44 func (d *Duration) UnmarshalJSON(data []byte) error { 45 // Ignore null, like in the main JSON package. 46 if string(data) == "null" { 47 return nil 48 } 49 var v any 50 if err := json.Unmarshal(data, &v); err != nil { 51 return err 52 } 53 switch value := v.(type) { 54 case float64: 55 *d = Duration(time.Duration(value)) 56 return nil 57 case string: 58 tmp, err := time.ParseDuration(value) 59 if err != nil { 60 return err 61 } 62 *d = Duration(tmp) 63 return nil 64 default: 65 return &time.ParseError{ 66 Layout: "", 67 Value: string(data), 68 LayoutElem: "", 69 ValueElem: "", 70 Message: "invalid duration", 71 } 72 } 73 } 74 75 func (d Duration) MarshalText() ([]byte, error) { 76 return json.Marshal(time.Duration(d).String()) 77 } 78 79 func (d *Duration) UnmarshalText(data []byte) error { 80 tmp, err := time.ParseDuration(string(data)) 81 if err != nil { 82 return err 83 } 84 *d = Duration(tmp) 85 return nil 86 }