Skip to content

Intermediate Gotchas

The Negative Duration That Lost a Second

a 1.5-second offset that becomes negative one

int main() {
  using namespace std::chrono;

  milliseconds offset{-1500};
  std::cout << "seconds: " << duration_cast<seconds>(offset).count() << '\n';
}

Does the conversion round -1.5 seconds down to -2?

Answer
seconds: -1

The fractional half-second was discarded toward zero.

Why

For integral duration representations, duration_cast scales the count and uses normal integer conversion rules. Dividing -1500 milliseconds by 1000 truncates toward zero, not toward negative infinity, so the result is -1. That is often correct for a conversion, but wrong for an earlier time bucket. C++17's std::chrono::floor expresses the latter intent.

The fix

const auto whole_seconds = std::chrono::floor<std::chrono::seconds>(offset);

Takeaway: duration_cast truncates toward zero; use chrono::floor when negative durations must round down.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry