From fd485c5383dd8480a04feaaa31161ae30bc3d3dd Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 4 Aug 2015 18:48:48 -0400 Subject: [PATCH] [X] Make months and years not convertible to seconds: * The Gregorian average of months and years is an integral number of seconds. * This patch slightly tweaks the average to make it not an integral number of seconds, and thus these units no longer implicitly convert to seconds. * This will flag naive mixing of years, months and seconds as a compile time error. --- date.h | 3 +- test/date_test/durations.pass.cpp | 48 +++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/date.h b/date.h index f7bd09e..49041d1 100644 --- a/date.h +++ b/date.h @@ -45,7 +45,8 @@ using weeks = std::chrono::duration , days::period>>; using years = std::chrono::duration - , days::period>>; + , days::period>, + std::ratio<1, 7>>>; using months = std::chrono::duration >>; diff --git a/test/date_test/durations.pass.cpp b/test/date_test/durations.pass.cpp index 9c01009..9be8f91 100644 --- a/test/date_test/durations.pass.cpp +++ b/test/date_test/durations.pass.cpp @@ -25,9 +25,53 @@ #include static_assert(date::days{1} == std::chrono::seconds{86400}, ""); +static_assert(date::days{1} == std::chrono::hours{24}, ""); +static_assert( std::is_convertible{}, ""); +static_assert( std::is_convertible{}, ""); +static_assert( std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); + static_assert(date::weeks{1} == std::chrono::seconds{604800}, ""); -static_assert(date::months{1} == std::chrono::seconds{2629746}, ""); -static_assert(date::years{1} == std::chrono::seconds{31556952}, ""); +static_assert(date::weeks{1} == date::days{7}, ""); +static_assert( std::is_convertible{}, ""); +static_assert( std::is_convertible{}, ""); +static_assert( std::is_convertible{}, ""); +static_assert( std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); + +static_assert( + std::chrono::seconds{2629745} < date::months{1} && + date::months{1} < std::chrono::seconds{2629746}, ""); +static_assert(date::days{30} < date::months{1} && date::months{1} < date::days{31}, ""); +static_assert(date::weeks{4} < date::months{1} && date::months{1} < date::weeks{5}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); + +static_assert( + std::chrono::seconds{31556951} < date::years{1} && + date::years{1} < std::chrono::seconds{31556952}, ""); +static_assert(date::days{365} < date::years{1} && date::years{1} < date::days{366}, ""); +static_assert(date::weeks{52} < date::years{1} && date::years{1} < date::weeks{53}, ""); +static_assert(date::years{1} == date::months{12}, ""); +static_assert( std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); +static_assert(!std::is_convertible{}, ""); static_assert(std::is_same{}, "");