github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/time/time.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package time contains a wrapper for time.Time in the standard library and 18 // associated methods. This package mainly exists to workaround an issue in Go 19 // where the serializer doesn't omit an empty value for time: 20 // https://github.com/golang/go/issues/11939. As such, this can be removed if a 21 // proposal is ever accepted for Go 22 package time 23 24 import ( 25 "bytes" 26 "time" 27 ) 28 29 // emptyString contains an empty JSON string value to be used as output 30 var emptyString = `""` 31 32 // Time is a convenience wrapper around stdlib time, but with different 33 // marshalling and unmarshaling for zero values 34 type Time struct { 35 time.Time 36 } 37 38 // Now returns the current time. It is a convenience wrapper around time.Now() 39 func Now() Time { 40 return Time{time.Now()} 41 } 42 43 func (t Time) MarshalJSON() ([]byte, error) { 44 if t.Time.IsZero() { 45 return []byte(emptyString), nil 46 } 47 48 return t.Time.MarshalJSON() 49 } 50 51 func (t *Time) UnmarshalJSON(b []byte) error { 52 if bytes.Equal(b, []byte("null")) { 53 return nil 54 } 55 // If it is empty, we don't have to set anything since time.Time is not a 56 // pointer and will be set to the zero value 57 if bytes.Equal([]byte(emptyString), b) { 58 return nil 59 } 60 61 return t.Time.UnmarshalJSON(b) 62 } 63 64 func Parse(layout, value string) (Time, error) { 65 t, err := time.Parse(layout, value) 66 return Time{Time: t}, err 67 } 68 func ParseInLocation(layout, value string, loc *time.Location) (Time, error) { 69 t, err := time.ParseInLocation(layout, value, loc) 70 return Time{Time: t}, err 71 } 72 73 func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time { 74 return Time{Time: time.Date(year, month, day, hour, min, sec, nsec, loc)} 75 } 76 77 func Unix(sec int64, nsec int64) Time { return Time{Time: time.Unix(sec, nsec)} } 78 79 func (t Time) Add(d time.Duration) Time { return Time{Time: t.Time.Add(d)} } 80 func (t Time) AddDate(years int, months int, days int) Time { 81 return Time{Time: t.Time.AddDate(years, months, days)} 82 } 83 func (t Time) After(u Time) bool { return t.Time.After(u.Time) } 84 func (t Time) Before(u Time) bool { return t.Time.Before(u.Time) } 85 func (t Time) Equal(u Time) bool { return t.Time.Equal(u.Time) } 86 func (t Time) In(loc *time.Location) Time { return Time{Time: t.Time.In(loc)} } 87 func (t Time) Local() Time { return Time{Time: t.Time.Local()} } 88 func (t Time) Round(d time.Duration) Time { return Time{Time: t.Time.Round(d)} } 89 func (t Time) Sub(u Time) time.Duration { return t.Time.Sub(u.Time) } 90 func (t Time) Truncate(d time.Duration) Time { return Time{Time: t.Time.Truncate(d)} } 91 func (t Time) UTC() Time { return Time{Time: t.Time.UTC()} }