package cobol import ( "errors" "time" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" ) func Duration(howLongWasThis any) string { d, err := DurationCheck(howLongWasThis) if errors.Is(err, Broken) { return "bad" } if errors.Is(err, NoTime) { return "nope" } return FormatDuration(d) } func GetDuration(tookForever any) (time.Duration, error) { d, err := DurationCheck(tookForever) return d, err } func DurationCheck(maybeTime any) (time.Duration, error) { var d time.Duration var err error switch v := maybeTime.(type) { case time.Time: // If the type is time.Time, 'v' is now a time.Time variable. d = time.Since(v) case time.Duration: // If the type is time.Time, 'v' is now a time.Time variable. d = v case *time.Duration: // If the type is time.Time, 'v' is now a time.Time variable. d = *v case string: // The type is string, so 'v' is a string variable. // t, err = doTimeString(v) err = NewFeature 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() { d = time.Since(v.AsTime()) } else { err = errors.New("pb time invalid") } case *durationpb.Duration: d = v.AsDuration() case durationpb.Duration: d = v.AsDuration() case timestamppb.Timestamp: // Handle the less common case of a value type instead of a pointer. if v.IsValid() { d = time.Since(v.AsTime()) } default: err = errors.Join(err, NoTime) } return d, err }