package cobol import ( "errors" "time" "google.golang.org/protobuf/types/known/timestamppb" ) // returns a human readable duration func Since(aLongTimeAgo any) string { s, err := SinceCheck(aLongTimeAgo) if errors.Is(err, Broken) { return "bad" } if errors.Is(err, NoTime) { return "nope" } return s } // returns a human readable duration // also returns errors func SinceCheck(mightBeRecently any) (string, error) { dur, err := GetSince(mightBeRecently) return FormatDuration(dur), err } func GetSince(maybeTime any) (time.Duration, error) { var t time.Time var err error switch v := maybeTime.(type) { case time.Time: // If the type is time.Time, 'v' is now a time.Time variable. t = v case *timestamppb.Timestamp: // If it's a protobuf Timestamp pointer (most common case), // 'v' is a *timestamppb.Timestamp. We must convert it. // It's also good to check if it's a valid timestamp. if v.IsValid() { t = v.AsTime() } else { err = errors.New("pb time invalid") } case timestamppb.Timestamp: // Handle the less common case of a value type instead of a pointer. if v.IsValid() { t = v.AsTime() } default: err = errors.Join(err, NoTime) } if err != nil { return time.Since(t), err } return time.Since(t), nil }