bug or documentation missing boost posix_time time_duration not_a_date_time
hi
please compile this program:
#include
On 23/05/2019 00:30, Erik Thiele wrote:
if the time_duration datatype is a complete partial order which is for example needed for it to be able to be sorted, then the above output is partly illegal:
if not a
if a<=b and b<=a then must be a=b. but this is not the case.
not_a_date_time is like a NaN. NaNs are weird like that. Returning true for the <= and >= operations is probably actually a bug; it's a side effect of using less_than_comparable when it should be using partially_ordered instead. You should raise an issue about that on GitHub or submit a PR to fix it.
so as expected the two vectors v0 and v1 are not equal after being sorted even though they certainly should be!
A default constructed time_duration is equal to zero duration. A not_a_date_time time_duration is not a zero duration. Why would you expect them to be equal?
i do not understand why time_duration is behaving in such a strange way here.
I am using time_duration(not_a_date_time) as a SQL-NULL value just like i am using date(not_a_date_time) and ptime(not_a_date_time) as SQL-NULL values.
SQL NULLs are weird, just like NaNs, so this should not be surprising to you.
Am Thu, 23 May 2019 11:18:43 +1200
schrieb Gavin Lambert via Boost-users
On 23/05/2019 00:30, Erik Thiele wrote:
if the time_duration datatype is a complete partial order which is for example needed for it to be able to be sorted, then the above output is partly illegal:
if not a
if a<=b and b<=a then must be a=b. but this is not the case.
not_a_date_time is like a NaN. NaNs are weird like that.
i don't think we should mix floating point issues with the date_time library.
Returning true for the <= and >= operations is probably actually a bug; it's a side effect of using less_than_comparable when it should be using partially_ordered instead. You should raise an issue about that on GitHub or submit a PR to fix it.
I will raise an issue.
so as expected the two vectors v0 and v1 are not equal after being sorted even though they certainly should be!
A default constructed time_duration is equal to zero duration. A not_a_date_time time_duration is not a zero duration. Why would you expect them to be equal?
I do not expect time_duration(not_a_date_time) and time_duration(hours(0)) to be equal. instead i expect them to be not equal. actually they are not equal, which is correctly reported by operator==. but i expect v0 and v1 to be equal because after sorting two vectors with the same contents must be equal. watch closely, v0 and v1 have the same elements. they are just push_backed in a different order. so after sorting v0 and v1, they need to be equal, but aren't. this is because operator< is not a complete partial order here.
i do not understand why time_duration is behaving in such a strange way here.
I am using time_duration(not_a_date_time) as a SQL-NULL value just like i am using date(not_a_date_time) and ptime(not_a_date_time) as SQL-NULL values.
SQL NULLs are weird, just like NaNs, so this should not be surprising to you.
I do not share the opinion that anything is weird :-) I was just looking for a reason for the asymmetry here. anyway i think it is not possible anymore to change this since there is too much code using the library out there and everybody is now used to this asymmetry. but the operator< issue can hopefully be fixed. i make a report. cu erik
On 23/05/2019 17:37, Erik Thiele wrote:
not_a_date_time is like a NaN. NaNs are weird like that.
i don't think we should mix floating point issues with the date_time library.
It's not implemented with an actual floating point NaN, but it is clearly intended to have equivalent behaviour. https://github.com/boostorg/date_time/blob/develop/include/boost/date_time/i... See the above code. Although interestingly unlike some floating point implementations, it looks like it does consider not_a_date_time == not_a_date_time. But yes, it should either give not_a_date_time an actual consistent relative ordering or use partially_ordered instead of less_than_comparable.
but i expect v0 and v1 to be equal because after sorting two vectors with the same contents must be equal. watch closely, v0 and v1 have the same elements. they are just push_backed in a different order. so after sorting v0 and v1, they need to be equal, but aren't. this is because operator< is not a complete partial order here.
Ah, I missed that part. But still, no. Sorting only uses operator<, and those operators are implemented consistently with NaN-like behaviour (partial ordering). In particular, it is *not* a "strict weak ordering", which is what std::sort assumes. not_a_date_time has no specific order, therefore sort is allowed to put it wherever it likes; you can't make any assumptions about its position relative to other values. It's not even required to group them together if they're spread out (although some sort algorithms might do that). If you don't like that behaviour, you can pass your own different comparator to sort which does assign a strict ordering to the values. For example, you can declare that not_a_date_time should be treated as strictly less than any actual duration. The bug you noticed in the <= and >= return values has no effect on sort.
I assume that time_duration is implemented as an integer. Some values
of this integer are then reserved for special values like
not_a_date_time.
this can be seen here:
https://github.com/boostorg/date_time/blob/develop/include/boost/date_time/i...
this should have the consequence that when studying the assembler code
for comparing two time_durations, all that happens is the assembler
code of "less than compare" for integer type. if additional comparisons
and branchings take place, then I assume the code is not meeting the
design criteria of being optimized.
Well... this is what I did, copy paste this code to justcompare.cpp:
#include
On 25/05/2019 01:41, Erik Thiele wrote:
I assume that time_duration is implemented as an integer. Some values of this integer are then reserved for special values like not_a_date_time.
this can be seen here:
https://github.com/boostorg/date_time/blob/develop/include/boost/date_time/i...
Yes, that's what I said before.
this should have the consequence that when studying the assembler code for comparing two time_durations, all that happens is the assembler code of "less than compare" for integer type. if additional comparisons and branchings take place, then I assume the code is not meeting the design criteria of being optimized.
No. That would be true if it were just delegating directly to the underlying integer comparison (which, FWIW, is what ptime does). int_adapter, however, intentionally performs a more complex comparison in order to treat the special values as special, and thus in an order different from their underlying integer "implementation detail". In particular, not_a_date_time is implemented as a NaN-like "not in any order". (For the purposes of sort, this tends to make it equivalent to any other value, and thus it can sort to anywhere at all in the list, usually remaining motionless.) Have a look at the implementation of int_adapter::compare in the above code. Whether this is the "right" choice, I don't know. But it's how it works, and it appears to have been intentional.
participants (2)
-
Erik Thiele
-
Gavin Lambert