github.com/cosmos/cosmos-proto@v1.0.0-beta.3/support/timepb/cmp.go (about) 1 package timepb 2 3 import ( 4 "fmt" 5 "time" 6 7 durpb "google.golang.org/protobuf/types/known/durationpb" 8 tspb "google.golang.org/protobuf/types/known/timestamppb" 9 ) 10 11 // IsZero returns true only when t is nil 12 func IsZero(t *tspb.Timestamp) bool { 13 return t == nil 14 } 15 16 // Commpare t1 and t2 and returns -1 when t1 < t2, 0 when t1 == t2 and 1 otherwise. 17 // Returns false if t1 or t2 is nil 18 func Compare(t1, t2 *tspb.Timestamp) int { 19 if t1 == nil || t2 == nil { 20 panic(fmt.Sprint("Can't compare nil time, t1=", t1, "t2=", t2)) 21 } 22 if t1.Seconds == t2.Seconds && t1.Nanos == t2.Nanos { 23 return 0 24 } 25 if t1.Seconds < t2.Seconds || t1.Seconds == t2.Seconds && t1.Nanos < t2.Nanos { 26 return -1 27 } 28 return 1 29 } 30 31 // DurationIsNegative returns true if the duration is negative. It assumes that d is valid 32 // (d..CheckValid() is nil). 33 func DurationIsNegative(d *durpb.Duration) bool { 34 return d.Seconds < 0 || d.Seconds == 0 && d.Nanos < 0 35 } 36 37 // AddStd returns a new timestamp with value t + d, where d is stdlib Duration. 38 // If t is nil then nil is returned. 39 // Panics on overflow. 40 func AddStd(t *tspb.Timestamp, d time.Duration) *tspb.Timestamp { 41 if t == nil { 42 return nil 43 } 44 if d == 0 { 45 t2 := *t 46 return &t2 47 } 48 t2 := tspb.New(t.AsTime().Add(d)) 49 overflowPanic(t, t2, d < 0) 50 return t2 51 } 52 53 func overflowPanic(t1, t2 *tspb.Timestamp, negative bool) { 54 cmp := Compare(t1, t2) 55 if negative { 56 if cmp < 0 { 57 panic("time overflow") 58 } 59 } else { 60 if cmp > 0 { 61 panic("time overflow") 62 } 63 } 64 } 65 66 const second = int32(time.Second) 67 68 // Add returns a new timestamp with value t + d, where d is protobuf Duration 69 // If t is nil then nil is returned. Panics on overflow. 70 // Note: d must be a valid PB Duration (d..CheckValid() is nil). 71 func Add(t *tspb.Timestamp, d *durpb.Duration) *tspb.Timestamp { 72 if t == nil { 73 return nil 74 } 75 if d.Seconds == 0 && d.Nanos == 0 { 76 t2 := *t 77 return &t2 78 } 79 t2 := tspb.Timestamp{ 80 Seconds: t.Seconds + d.Seconds, 81 Nanos: t.Nanos + d.Nanos, 82 } 83 if t2.Nanos >= second { 84 t2.Nanos -= second 85 t2.Seconds++ 86 } else if t2.Nanos <= -second { 87 t2.Nanos += second 88 t2.Seconds-- 89 } 90 overflowPanic(t, &t2, DurationIsNegative(d)) 91 return &t2 92 }