// The MIT License (MIT) // // Copyright (c) 2016 Howard Hinnant // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // This test is meant to maintain a record of the sizeof each type. #include "date.h" #include #include void test_a() { using namespace date; { // correct abbreviation std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%A %F", tp); // this may fail with libstdc++, see https://github.com/HowardHinnant/date/issues/388 // possible workaround: compile date.h with -DONLY_C_LOCALE=1 assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"Sunday 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"Sunday 2016-12-11"}; sys_days tp; in >> parse("%A %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // not a valid name std::istringstream in{"Dec 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } { // wrong name std::istringstream in{"Sat 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } { // extra ws in input std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // extra ws in format std::istringstream in{"Sun 2016-12-11"}; sys_days tp; in >> parse("%a %F", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } } void test_b() { using namespace date; { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%B %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct abbreviation std::istringstream in{"Dec 11 2016"}; sys_days tp; in >> parse("%h %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%B %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // correct full name std::istringstream in{"December 11 2016"}; sys_days tp; in >> parse("%h %d %Y", tp); assert(!in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 2016_y/12/11); } { // incorrect abbreviation std::istringstream in{"Dece 11 2016"}; sys_days tp; in >> parse("%b %d %Y", tp); assert( in.fail()); assert(!in.bad()); assert(!in.eof()); assert(tp == 1970_y/1/1); } } void test_c() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"Sun Dec 11 14:02:43 2016"}; sys_seconds tp; in >> parse("%c", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43}); } } void test_x() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"12/11/16"}; sys_seconds tp; in >> parse("%x", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11}); } } void test_X() { using namespace date; using namespace std::chrono; { // correct abbreviation std::istringstream in{"2016-12-11 14:02:43"}; sys_seconds tp; in >> parse("%F %X", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{14} + minutes{2} + seconds{43}); } } void test_C() { using namespace date; using namespace std::chrono; { std::istringstream in{"20 16 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/11); } { std::istringstream in{"-2 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -101_y/12/11); } { std::istringstream in{"-1 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -100_y/12/11); } { std::istringstream in{"-1 99 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -99_y/12/11); } { std::istringstream in{"-1 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == -1_y/12/11); } { std::istringstream in{"0 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 0_y/12/11); } { std::istringstream in{"0 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 1_y/12/11); } { std::istringstream in{"0 99 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 99_y/12/11); } { std::istringstream in{"1 0 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 100_y/12/11); } { std::istringstream in{"1 1 12 11"}; sys_days tp; in >> parse("%C %y %m %d", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 101_y/12/11); } } void test_d() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 09 12"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 09 12"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 9 12"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 9 12"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/9); } { std::istringstream in{"2016 31 11"}; sys_days tp; in >> parse("%Y %e %m", tp); assert(in.fail()); } } void test_D() { using namespace date; using namespace std::chrono; { std::istringstream in{"12/11/16"}; sys_days tp; in >> parse("%D", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/11); } } void test_F() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-13"}; sys_days tp; in >> parse("%F", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/13); } { std::istringstream in{"2016-12-13"}; year_month_day tp; in >> parse("%F", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/12/13); } } void test_H() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_time tp; in >> parse("%F %H", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15}); } { std::istringstream in{"2016-12-11 24"}; sys_time tp; in >> parse("%F %H", tp); assert(in.fail()); } } void test_Ip() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 1 pm"}; sys_time tp; in >> parse("%F %I %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{13}); } { std::istringstream in{"2016-12-11 1 am"}; sys_time tp; in >> parse("%F %I %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{1}); } { std::istringstream in{"2016-12-11 13 am"}; sys_time tp; in >> parse("%F %I %p", tp); assert(in.fail()); } } void test_j() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 361"}; sys_days tp; in >> parse("%Y %j", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_m() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016 12 09"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/9/12); } { std::istringstream in{"2016 12 9"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == 2016_y/9/12); } { std::istringstream in{"2016 12 13"}; sys_days tp; in >> parse("%Y %d %m", tp); assert(in.fail()); } } void test_M() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_time tp; in >> parse("%F %M", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + minutes{15}); } { std::istringstream in{"2016-12-11 65"}; sys_time tp; in >> parse("%F %M", tp); assert(in.fail()); } } void test_S() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15"}; sys_seconds tp; in >> parse("%F %S", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + seconds{15}); } { std::istringstream in{"2016-12-11 15.001"}; sys_time tp; in >> parse("%F %S", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + seconds{15} + milliseconds{1}); } { std::istringstream in{"2016-12-11 60"}; sys_seconds tp; in >> parse("%F %S", tp); assert(in.fail()); } } void test_T() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 15:43:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22}); } { std::istringstream in{"2016-12-11 15:43:22.001"}; sys_time tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22} + milliseconds{1}); } { std::istringstream in{"2016-12-11 15:43:22"}; sys_time tp; in >> parse("%F %T", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{15} + minutes{43} + seconds{22}); } { std::istringstream in{"15:43:22.001"}; milliseconds d; in >> parse("%T", d); assert(!in.fail()); assert(!in.bad()); assert(d == hours{15} + minutes{43} + seconds{22} + milliseconds{1}); } { std::istringstream in{"2016-12-11 24:43:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } { std::istringstream in{"2016-12-11 15:60:22"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } { std::istringstream in{"2016-12-11 15:43:60"}; sys_seconds tp; in >> parse("%F %T", tp); assert(in.fail()); } } void test_p() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-11 11pm"}; sys_time tp; in >> parse("%F %I%p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/11} + hours{23}); } { std::istringstream in{"1986-12-01 01:01:01 pm"}; sys_time tp; in >> parse("%Y-%m-%d %I:%M:%S %p", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{1986_y/12/01} + hours{13} + minutes{01} + seconds{01}); } { std::istringstream in{"1986-12-01 01:01:01"}; sys_time tp; in >> parse("%Y-%m-%d %I:%M:%S", tp); // The test will fail because %I needs the %p option to shows if it is AM or PM assert(in.fail()); } } void test_r() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 1:36:57 pm"}; sys_seconds tp; in >> parse("%F %r", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36} + seconds{57}); } } void test_R() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 13:36"}; sys_seconds tp; in >> parse("%F %R", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{13} + minutes{36}); } } void test_U() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%Y-%U-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_W() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%Y-%W-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_GV() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%G-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"2016-52-1"}; sys_days tp; in >> parse("%G-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"20 16-52-1"}; sys_days tp; in >> parse("%C %g-%V-%w", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } { std::istringstream in{"20 16-52-1"}; sys_days tp; in >> parse("%C %g-%V-%u", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26}); } } void test_z() { using namespace date; using namespace std::chrono; { std::istringstream in{"2016-12-26 15:53:22 -0500"}; sys_seconds tp; in >> parse("%F %T %z", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22}); } { std::istringstream in{"2016-12-26 15:53:22 -0500"}; local_seconds tp; in >> parse("%F %T %z", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22}); } { std::istringstream in{"2016-12-26 15:53:22 -05:00"}; sys_seconds tp; in >> parse("%F %T %Ez", tp); assert(!in.fail()); assert(!in.bad()); assert(tp == sys_days{2016_y/12/26} + hours{20} + minutes{53} + seconds{22}); } } void test_Z() { using namespace date; using namespace std::chrono; { std::string a; std::istringstream in{"2016-12-26 15:53:22 word"}; local_seconds tp; in >> parse("%F %T %Z", tp, a); assert(!in.fail()); assert(!in.bad()); assert(tp == local_days{2016_y/12/26} + hours{15} + minutes{53} + seconds{22}); assert(a == "word"); } } void test_trailing_Z() { std::string format = "%FT%TZ"; std::string datetime = "2017-2-15T13:13:13"; std::istringstream input(datetime); date::sys_seconds tp; input >> date::parse(format, tp); assert(input.fail()); assert(input.eof()); } void test_leading_ws() { using namespace std; using namespace date; istringstream in{"05/04/17 5/4/17"}; year_month_day d1, d2; in >> parse("%D", d1) >> parse("%n%D", d2); assert(d1 == may/4/2017); assert(d2 == may/4/2017); } void test_space() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse(" %D", d1); assert(d1 == may/4/2017); } } void test_n() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(in.fail()); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%n%D", d1); assert(in.fail()); } } void test_t() { using namespace std; using namespace date; { istringstream in{"05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(d1 == may/4/2017); } { istringstream in{" 05/04/17"}; year_month_day d1; in >> parse("%t%D", d1); assert(in.fail()); } } int main() { test_a(); test_b(); test_c(); test_C(); test_d(); test_D(); test_F(); test_H(); test_Ip(); test_j(); test_m(); test_M(); test_p(); test_r(); test_R(); test_S(); test_T(); test_U(); test_W(); test_GV(); test_x(); test_X(); test_z(); test_Z(); test_trailing_Z(); test_leading_ws(); test_space(); test_n(); test_t(); }