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) if dur == nil { return FormatDuration(time.Second), NoDuration } return FormatDuration(*dur), err } func GetSince(maybeTime any) (*time.Duration, error) { var err error switch v := maybeTime.(type) { case time.Time: // If the type is time.Time, 'v' is now a time.Time variable. dur := time.Since(v) return &dur, nil 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() { dur := time.Since(v.AsTime()) return &dur, nil } 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() { dur := time.Since(v.AsTime()) return &dur, nil } default: err = errors.Join(err, NoTime) } return nil, err }