This is part of https://wg21.link/P0355R7. I am adding these methods
to provide an alternative for the {from,to}_time_t methods that were
removed in https://llvm.org/D113027.
Details
- Reviewers
mstorsjo ldionne - Group Reviewers
Restricted Project - Commits
- rGdce5fc56b619: [libc++] Implement file_clock::{to,from}_sys
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libcxx/include/chrono | ||
---|---|---|
2822 | IIUC, both the system_clock and file_clock have the same Epochs (the Unix one) on all the platforms we support. So we shouldn't need to do any additional adjustment here AFAIU. Same for from_sys. |
libcxx/docs/ReleaseNotes.rst | ||
---|---|---|
83–86 | Instead, in C++20 you can use...? | |
libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp | ||
34–37 | Naming nit: When I see various variables named foo_now, it fires my red-flag detector for TOCTTOU vulnerabilities. In this case, file_now is arguably a "now," but sys_now is clearly a "then," because by the time we've computed it, "now" is later than before. ;) I suggest just ft and st, here and below. (You can still initialize ft with file_clock::now() if you're confident you won't mind whatever's going to happen to this test on DST day or whatever. I just don't like the variable's own name to include the word now.) | |
47–58 | Here, this is a good use of variables named foo_now. :) assert(std::chrono::milliseconds(-500) < diff && diff < std::chrono::milliseconds(500)); just to be on the safe side. (And notice my usual preference for () in object-factory-style constructors, idiomatically reserving {} for braced initializer lists.) | |
60–67 | In many cases we'll have sys_diff == file_diff == 0, right? LIBCPP_ASSERT(std::is_same_v<decltype(sys_diff), decltype(file_diff)>); ? |
Address review comments. Thanks!
libcxx/docs/ReleaseNotes.rst | ||
---|---|---|
83–86 | Oh, yeah, somehow I thought the from_time_t we removed was C++20 only. Will adjust to basically say "move to C++20", since this whole file_clock thing is supposed to be C++20 anyways. For some reason I would have bet that it was C++17 since it is tied to filesystem -- oh well. | |
libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp | ||
60–67 |
No, we don't. Or at least I don't. In my mind, decltype(sys_diff) is chrono::duration<representation-of-system-clock, period-of-system-clock> whereas decltype(file_diff) is chrono::duration<representation-of-file-clock, period-of-file-clock>, and both don't need to be the same. And in fact they aren't in our implementation (system clock has rep = long long, period = milliseconds and file clock has rep = int128_t, period = nanoseconds). Both should be "equal", in the sense that if you convert both to the least granular measurement, you should get the same answer. However, both are not necessarily going to equal 0 ticks, because the two time stamps were not taken at the same time. In practice I expect the difference will be very small because there's almost no time between the two calls to now(), but we still should not assume it is 0. |
libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp | ||
---|---|---|
30 | Btw, IMO it'd be nice to get rid of this line and use std::chrono:: everywhere, for greppability. | |
60–67 |
Right; what I meant was more in the line of "flaky tests." Here we have a test where — maybe not 99% of the time, but some significant fraction of the time — it's testing that 0 == 0; and then some small-and-nonreproducible remainder of the time, it's testing something-other-than-that. This is a "testing code smell." It would be strictly better if we could do something like auto const ft = chrono::file_clock::time_point("2021-01-01 01:23:45"); auto const st = chrono::system_clock::time_point("2021-01-01 01:23:45"); auto sys_diff = chrono::file_clock::to_sys(ft) - st; auto file_diff = ft - chrono::file_clock::from_sys(st); assert(sys_diff == file_diff); but I don't know that such a primitive for generating timepoints exists (or if it does, it's probably in the date stuff we haven't implemented yet). |
libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp | ||
---|---|---|
60–67 | I agree and would 100% have written the test that way, but as you say, we don't have a good way of generating a time point besides now(). |
Instead, in C++20 you can use...?
But what about prior to C++20? Even if the answer is "go jump in a lake," I think it's worth release-noting that. :)