datetime_ut.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include "datetime.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/string/builder.h>
  4. Y_UNIT_TEST_SUITE(TSimpleTMTest) {
  5. TString PrintMarker(const TString& test, int line) {
  6. return TStringBuilder() << "test " << test << " at line " << line;
  7. }
  8. TString JoinMarker(const TString& marker, time_t t) {
  9. return TStringBuilder() << marker << " (tstamp=" << t << ")";
  10. }
  11. TString PrintMarker(const TString& test, int line, time_t t) {
  12. return JoinMarker(PrintMarker(test, line), t);
  13. }
  14. void AssertStructTmEqual(const TString& marker, const struct tm& tmt, const NDatetime::TSimpleTM& tms) {
  15. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Sec, tmt.tm_sec, marker);
  16. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Min, tmt.tm_min, marker);
  17. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Hour, tmt.tm_hour, marker);
  18. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.WDay, tmt.tm_wday, marker);
  19. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.MDay, tmt.tm_mday, marker);
  20. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Mon, tmt.tm_mon, marker);
  21. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.YDay, tmt.tm_yday, marker);
  22. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Year, tmt.tm_year, marker);
  23. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.IsDst, tmt.tm_isdst, marker);
  24. #ifndef _win_
  25. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.GMTOff, tmt.tm_gmtoff, marker);
  26. #endif
  27. }
  28. void AssertSimpleTM(const TString& mark,
  29. const NDatetime::TSimpleTM& tms,
  30. time_t tstamp, ui32 year, ui32 mon, ui32 mday, ui32 hour, ui32 minu, ui32 sec) {
  31. TString marker = JoinMarker(mark, tstamp);
  32. struct tm tmt;
  33. Zero(tmt);
  34. GmTimeR(&tstamp, &tmt);
  35. AssertStructTmEqual(marker, tmt, tms);
  36. tmt = tms.AsStructTmUTC();
  37. time_t tstamp1 = TimeGM(&tmt);
  38. UNIT_ASSERT_VALUES_EQUAL_C(tstamp, tstamp1, marker);
  39. UNIT_ASSERT_VALUES_EQUAL_C(tstamp, tms.AsTimeT(), marker);
  40. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.RealYear(), year, marker);
  41. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.RealMonth(), mon, marker);
  42. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.MDay, mday, marker);
  43. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Hour, hour, marker);
  44. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Min, minu, marker);
  45. UNIT_ASSERT_VALUES_EQUAL_C((int)tms.Sec, sec, marker);
  46. }
  47. Y_UNIT_TEST(TestLeap) {
  48. using namespace NDatetime;
  49. UNIT_ASSERT(LeapYearAD(2000));
  50. UNIT_ASSERT(LeapYearAD(2012));
  51. UNIT_ASSERT(!LeapYearAD(1999));
  52. UNIT_ASSERT(LeapYearAD(2004));
  53. UNIT_ASSERT(!LeapYearAD(1900));
  54. }
  55. Y_UNIT_TEST(TestYDayConversion) {
  56. using namespace NDatetime;
  57. ui32 month;
  58. ui32 mday;
  59. for (ui32 yday = 0; yday < 365; ++yday) {
  60. YDayToMonthAndDay(yday, false, &month, &mday);
  61. UNIT_ASSERT_VALUES_EQUAL(yday, YDayFromMonthAndDay(month, mday, false));
  62. }
  63. for (ui32 yday = 0; yday < 366; ++yday) {
  64. YDayToMonthAndDay(yday, true, &month, &mday);
  65. UNIT_ASSERT_VALUES_EQUAL(yday, YDayFromMonthAndDay(month, mday, true));
  66. }
  67. UNIT_ASSERT_EXCEPTION(YDayToMonthAndDay(365, false, &month, &mday), yexception);
  68. UNIT_ASSERT_EXCEPTION(YDayToMonthAndDay(366, true, &month, &mday), yexception);
  69. }
  70. Y_UNIT_TEST(SimpleTMTest) {
  71. using namespace NDatetime;
  72. tzset();
  73. TSimpleTM::New(-1); // should not die here
  74. UNIT_ASSERT_VALUES_EQUAL((ui32)0, (ui32)TSimpleTM::New(0));
  75. UNIT_ASSERT((ui32)TSimpleTM::New(0).IsUTC());
  76. time_t t = time(nullptr);
  77. {
  78. struct tm tmt;
  79. Zero(tmt);
  80. gmtime_r(&t, &tmt);
  81. UNIT_ASSERT_VALUES_EQUAL_C((i64)t, (i64)TSimpleTM::New(t).AsTimeT(), ToString(t)); // time_t -> gmt tm -> time_t
  82. UNIT_ASSERT_VALUES_EQUAL_C((i64)t, (i64)TSimpleTM::New(tmt).AsTimeT(), ToString(t)); // gmt tm -> time_t
  83. AssertStructTmEqual(PrintMarker("UTC:time_t", __LINE__, t),
  84. tmt, TSimpleTM::New(t));
  85. AssertStructTmEqual(PrintMarker("UTC:tm", __LINE__, t),
  86. tmt, TSimpleTM::New(tmt));
  87. UNIT_ASSERT(TSimpleTM::New(t).IsUTC());
  88. UNIT_ASSERT(TSimpleTM::New(tmt).IsUTC());
  89. }
  90. {
  91. struct tm tmt;
  92. Zero(tmt);
  93. localtime_r(&t, &tmt);
  94. UNIT_ASSERT_VALUES_EQUAL((i64)t, (i64)TSimpleTM::NewLocal(t).AsTimeT()); // time_t -> local tm -> time_t
  95. UNIT_ASSERT_VALUES_EQUAL((i64)t, (i64)TSimpleTM::New(tmt).AsTimeT());
  96. AssertStructTmEqual(PrintMarker("local:time_t", __LINE__, t),
  97. tmt, TSimpleTM::NewLocal(t));
  98. AssertStructTmEqual(PrintMarker("local:tm", __LINE__, t),
  99. tmt, TSimpleTM::New(tmt));
  100. AssertStructTmEqual(PrintMarker("local:tm:RegenerateFields", __LINE__, t),
  101. tmt, TSimpleTM::New(tmt).RegenerateFields());
  102. AssertStructTmEqual(PrintMarker("local:time_t:SetRealDate", __LINE__, t),
  103. tmt, TSimpleTM::NewLocal(t).SetRealDate(tmt.tm_year + 1900, tmt.tm_mon + 1, tmt.tm_mday, tmt.tm_hour, tmt.tm_min, tmt.tm_sec, tmt.tm_isdst));
  104. }
  105. {
  106. TSimpleTM tt = TSimpleTM::New(0);
  107. tt.SetRealDate(2012, 3, 30, 5, 6, 7);
  108. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  109. tt, 1333083967, 2012, 3, 30, 5, 6, 7);
  110. tt.SetRealDate(2012, 3, 8, 5, 6, 7);
  111. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  112. tt, 1331183167, 2012, 3, 8, 5, 6, 7);
  113. tt.SetRealDate(2010, 10, 4, 5, 6, 7);
  114. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  115. tt, 1286168767, 2010, 10, 4, 5, 6, 7);
  116. tt.Add(TSimpleTM::F_MON);
  117. AssertSimpleTM(PrintMarker("UTC:AddMonth", __LINE__),
  118. tt, 1288847167, 2010, 11, 4, 5, 6, 7);
  119. tt.Add(TSimpleTM::F_DAY);
  120. AssertSimpleTM(PrintMarker("UTC:AddDay", __LINE__),
  121. tt, 1288933567, 2010, 11, 5, 5, 6, 7);
  122. tt.Add(TSimpleTM::F_YEAR);
  123. AssertSimpleTM(PrintMarker("UTC:AddYear", __LINE__),
  124. tt, 1320469567, 2011, 11, 5, 5, 6, 7);
  125. for (ui32 i = 0; i < 365; ++i) {
  126. tt.Add(TSimpleTM::F_DAY);
  127. }
  128. AssertSimpleTM(PrintMarker("UTC:365*AddDay", __LINE__),
  129. tt, 1352005567, 2012, 11, 4, 5, 6, 7);
  130. tt.Add(TSimpleTM::F_MON, -10);
  131. AssertSimpleTM(PrintMarker("UTC:AddMonth(-10)", __LINE__),
  132. tt, 1325653567, 2012, 1, 4, 5, 6, 7);
  133. tt.Add(TSimpleTM::F_HOUR, -24 * 4 - 6);
  134. AssertSimpleTM(PrintMarker("UTC:AddHour(-102)", __LINE__),
  135. tt, 1325286367, 2011, 12, 30, 23, 6, 7);
  136. }
  137. {
  138. TSimpleTM tt = TSimpleTM::New();
  139. tt.SetRealDate(2012, 2, 29);
  140. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  141. tt, 1330473600, 2012, 2, 29, 0, 0, 0);
  142. tt.SetRealDate(2012, 2, 29);
  143. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  144. tt, 1330473600, 2012, 2, 29, 0, 0, 0);
  145. tt.SetRealDate(2013, 12, 28);
  146. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  147. tt, 1388188800, 2013, 12, 28, 0, 0, 0);
  148. tt.SetRealDate(2012, 10, 23);
  149. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  150. tt, 1350950400, 2012, 10, 23, 0, 0, 0);
  151. tt.SetRealDate(2013, 3, 16);
  152. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  153. tt, 1363392000, 2013, 3, 16, 0, 0, 0);
  154. tt.SetRealDate(2013, 2, 17);
  155. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  156. tt, 1361059200, 2013, 2, 17, 0, 0, 0);
  157. tt.SetRealDate(2012, 12, 23);
  158. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  159. tt, 1356220800, 2012, 12, 23, 0, 0, 0);
  160. tt.SetRealDate(2012, 5, 17);
  161. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  162. tt, 1337212800, 2012, 5, 17, 0, 0, 0);
  163. tt.SetRealDate(2012, 6, 15);
  164. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  165. tt, 1339718400, 2012, 6, 15, 0, 0, 0);
  166. tt.SetRealDate(2009, 3, 17);
  167. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  168. tt, 1237248000, 2009, 3, 17, 0, 0, 0);
  169. tt.SetRealDate(2013, 8, 12);
  170. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  171. tt, 1376265600, 2013, 8, 12, 0, 0, 0);
  172. tt.SetRealDate(2015, 12, 11, 10, 9, 8);
  173. AssertSimpleTM(PrintMarker("UTC:SetRealDate", __LINE__),
  174. tt, 1449828548, 2015, 12, 11, 10, 9, 8);
  175. }
  176. }
  177. }