13

So in the Chrono Library provides, duration_cast:

Computations are done in the widest type available and converted, as if by static_cast, to the result type only when finished

And 's floor:

Returns the greatest duration t representable in ToDuration that is less or equal to d

So for all x will the result of these 2 calls be equal:

  1. chrono::duration_cast<chrono::seconds>(x)
  2. chrono::floor<chrono::seconds>(x)
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

1 Answers1

15

As far as I can tell, same as the difference between static_cast and std::floor: Negatives are rounded down instead of truncated toward zero.

#include <iostream>
#include <chrono>
using namespace std::chrono_literals;

int main() {
    std::cout << "duration_cast:" << std::endl;
    std::cout << "1.4s: " << std::chrono::duration_cast<std::chrono::seconds>(1400ms).count() << std::endl;
    std::cout << "1.5s: " << std::chrono::duration_cast<std::chrono::seconds>(1500ms).count() << std::endl;
    std::cout << "1.6s: " << std::chrono::duration_cast<std::chrono::seconds>(1600ms).count() << std::endl;
    std::cout << "-1.4s: " << std::chrono::duration_cast<std::chrono::seconds>(-1400ms).count() << std::endl;
    std::cout << "-1.5s: " << std::chrono::duration_cast<std::chrono::seconds>(-1500ms).count() << std::endl;
    std::cout << "-1.6s: " << std::chrono::duration_cast<std::chrono::seconds>(-1600ms).count() << std::endl;

    std::cout << "floor:" << std::endl;
    std::cout << "1.4s: " << std::chrono::floor<std::chrono::seconds>(1400ms).count() << std::endl;
    std::cout << "1.5s: " << std::chrono::floor<std::chrono::seconds>(1500ms).count() << std::endl;
    std::cout << "1.6s: " << std::chrono::floor<std::chrono::seconds>(1600ms).count() << std::endl;
    std::cout << "-1.4s: " << std::chrono::floor<std::chrono::seconds>(-1400ms).count() << std::endl;
    std::cout << "-1.5s: " << std::chrono::floor<std::chrono::seconds>(-1500ms).count() << std::endl;
    std::cout << "-1.6s: " << std::chrono::floor<std::chrono::seconds>(-1600ms).count() << std::endl;
    return 0;
}

.

duration_cast:
1.4s: 1
1.5s: 1
1.6s: 1
-1.4s: -1
-1.5s: -1
-1.6s: -1
floor:
1.4s: 1
1.5s: 1
1.6s: 1
-1.4s: -2
-1.5s: -2
-1.6s: -2

https://wandbox.org/permlink/SsmpRz6RkvbL6Sru

0x5453
  • 12,753
  • 1
  • 32
  • 61
  • 12
    Correct. And this becomes very necessary when dealing with a `system_clock::time_point` that represents a point in time prior to 1970, and you want to truncate it to a count of days prior to 1970: `auto d = floor(tp);`. `time_point_cast` would round up towards the next day, whereas `floor` rounds down to the start of the day which `tp` refers to. Similar issues with `durations`, but the killer app for `floor` is making calendrical computations work for pre-1970 dates. – Howard Hinnant Jan 26 '18 at 19:33
  • 4
    Ah, we've been graced by a visit from the time lord himself, @HowardHinnant just to put a plug in for his wisdom, check this out: https://github.com/HowardHinnant/date – Jonathan Mee Jan 26 '18 at 19:39