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();
}