absl::Status TimestampDiff()

in sql_utils/public/functions/date_time_util.cc [3999:4051]


absl::Status TimestampDiff(absl::Time timestamp1, absl::Time timestamp2,
                           DateTimestampPart part, int64_t* output) {
  absl::Duration duration = timestamp1 - timestamp2;
  absl::Duration rem;
  absl::Duration divide;
  switch (part) {
    case DAY:
      divide = absl::Hours(24);
      break;
    case HOUR:
      divide = absl::Hours(1);
      break;
    case MINUTE:
      divide = absl::Minutes(1);
      break;
    case SECOND:
      divide = absl::Seconds(1);
      break;
    case MILLISECOND:
      divide = absl::Milliseconds(1);
      break;
    case MICROSECOND:
      divide = absl::Microseconds(1);
      break;
    case NANOSECOND:
      divide = absl::Nanoseconds(1);
      break;
    case YEAR:
    case QUARTER:
    case MONTH:
    case DATE:
    case DAYOFWEEK:
    case DAYOFYEAR:
    case WEEK:
      return MakeEvalError() << "Unsupported DateTimestampPart "
                             << DateTimestampPart_Name(part);
    default:
      return MakeEvalError()
             << "Unexpected DateTimestampPart " << DateTimestampPart_Name(part);
  }
  *output = absl::IDivDuration(duration, divide, &rem);
  // If we make sure the input timestamps are always valid, we can only do this
  // check for nano.
  if ((*output == std::numeric_limits<int64_t>::max() ||
       *output == std::numeric_limits<int64_t>::lowest()) &&
      rem != absl::ZeroDuration()) {
    return MakeEvalError() << "TIMESTAMP_DIFF at "
                           << DateTimestampPart_Name(part)
                           << " precision between values of " << timestamp1
                           << " and " << timestamp2 << " causes overflow";
  }
  return absl::OkStatus();
}