LocalDateTimeTest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. //
  2. // LocalDateTimeTest.cpp
  3. //
  4. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  5. // and Contributors.
  6. //
  7. // SPDX-License-Identifier: BSL-1.0
  8. //
  9. #include "LocalDateTimeTest.h"
  10. #include "CppUnit/TestCaller.h"
  11. #include "CppUnit/TestSuite.h"
  12. #include "Poco/LocalDateTime.h"
  13. #include "Poco/DateTime.h"
  14. #include "Poco/Timestamp.h"
  15. #include "Poco/Timespan.h"
  16. #include "Poco/Timezone.h"
  17. #include "Poco/DateTimeFormat.h"
  18. #include "Poco/DateTimeFormatter.h"
  19. #include <ctime>
  20. #include <iostream>
  21. #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
  22. #include "wce_time.h"
  23. #endif
  24. using Poco::LocalDateTime;
  25. using Poco::DateTime;
  26. using Poco::Timestamp;
  27. using Poco::Timespan;
  28. using Poco::Timezone;
  29. #ifndef _WIN32_WCE
  30. using std::strftime;
  31. #endif
  32. LocalDateTimeTest::LocalDateTimeTest(const std::string& name): CppUnit::TestCase(name)
  33. {
  34. }
  35. LocalDateTimeTest::~LocalDateTimeTest()
  36. {
  37. }
  38. void LocalDateTimeTest::testGregorian1()
  39. {
  40. LocalDateTime dt(1970, 1, 1);
  41. assertTrue (dt.year() == 1970);
  42. assertTrue (dt.month() == 1);
  43. assertTrue (dt.day() == 1);
  44. assertTrue (dt.hour() == 0);
  45. assertTrue (dt.minute() == 0);
  46. assertTrue (dt.second() == 0);
  47. assertTrue (dt.millisecond() == 0);
  48. assertTrue (dt.dayOfWeek() == 4);
  49. // REMOVED: this fails when the current DST offset differs from
  50. // the one on 1970-1-1
  51. //assertTrue (dt.tzd() == Timezone::tzd());
  52. assertTrue (dt.julianDay() == 2440587.5);
  53. dt.assign(2001, 9, 9, 1, 46, 40);
  54. assertTrue (dt.year() == 2001);
  55. assertTrue (dt.month() == 9);
  56. assertTrue (dt.day() == 9);
  57. assertTrue (dt.hour() == 1);
  58. assertTrue (dt.minute() == 46);
  59. assertTrue (dt.second() == 40);
  60. assertTrue (dt.millisecond() == 0);
  61. assertTrue (dt.dayOfWeek() == 0);
  62. //assertTrue (dt.tzd() == Timezone::tzd());
  63. assertEqualDelta (dt.julianDay(), 2452161.574074, 0.000001);
  64. }
  65. void LocalDateTimeTest::testGregorian2()
  66. {
  67. LocalDateTime dt(2*3600, 1970, 1, 1, 0, 0, 0, 0, 0);
  68. assertTrue (dt.year() == 1970);
  69. assertTrue (dt.month() == 1);
  70. assertTrue (dt.day() == 1);
  71. assertTrue (dt.hour() == 0);
  72. assertTrue (dt.minute() == 0);
  73. assertTrue (dt.second() == 0);
  74. assertTrue (dt.millisecond() == 0);
  75. assertTrue (dt.dayOfWeek() == 4);
  76. assertTrue (dt.tzd() == 2*3600);
  77. dt.assign(-7*3600, 2001, 9, 9, 1, 46, 40, 0, 0);
  78. assertTrue (dt.year() == 2001);
  79. assertTrue (dt.month() == 9);
  80. assertTrue (dt.day() == 9);
  81. assertTrue (dt.hour() == 1);
  82. assertTrue (dt.minute() == 46);
  83. assertTrue (dt.second() == 40);
  84. assertTrue (dt.millisecond() == 0);
  85. assertTrue (dt.dayOfWeek() == 0);
  86. assertTrue (dt.tzd() == -7*3600);
  87. }
  88. void LocalDateTimeTest::testConversions()
  89. {
  90. LocalDateTime dt1(2*3600, 2005, 1, 28, 14, 24, 44, 234, 0);
  91. LocalDateTime dt2(dt1.tzd(), dt1.utc());
  92. LocalDateTime dt3;
  93. dt3 = dt1;
  94. LocalDateTime dt4(dt2);
  95. LocalDateTime dt5(-4*3600, dt1.utc());
  96. assertTrue (dt2.year() == 2005);
  97. assertTrue (dt2.month() == 1);
  98. assertTrue (dt2.day() == 28);
  99. assertTrue (dt2.hour() == 14);
  100. assertTrue (dt2.minute() == 24);
  101. assertTrue (dt2.second() == 44);
  102. assertTrue (dt2.millisecond() == 234);
  103. assertTrue (dt2.dayOfWeek() == 5);
  104. assertTrue (dt2.tzd() == 2*3600);
  105. assertTrue (dt5.year() == 2005);
  106. assertTrue (dt5.month() == 1);
  107. assertTrue (dt5.day() == 28);
  108. assertTrue (dt5.hour() == 8);
  109. assertTrue (dt5.minute() == 24);
  110. assertTrue (dt5.second() == 44);
  111. assertTrue (dt5.millisecond() == 234);
  112. assertTrue (dt5.dayOfWeek() == 5);
  113. assertTrue (dt5.tzd() == -4*3600);
  114. DateTime dt6(2005, 1, 28, 14, 24, 44, 234, 0);
  115. LocalDateTime dt7(3600, dt6);
  116. LocalDateTime dt8(3600, dt6, false);
  117. LocalDateTime dt9(3600, dt6, true);
  118. assertTrue (dt7.hour() == 15);
  119. assertTrue (dt8.hour() == 14);
  120. assertTrue (dt9.hour() == 15);
  121. }
  122. void LocalDateTimeTest::testCalcs()
  123. {
  124. LocalDateTime dt1(2005, 1, 1);
  125. assertTrue (dt1.dayOfYear() == 1);
  126. assertTrue (dt1.week(DateTime::MONDAY) == 0);
  127. dt1.assign(2005, 1, 3);
  128. assertTrue (dt1.dayOfYear() == 3);
  129. assertTrue (dt1.week(DateTime::MONDAY) == 1);
  130. dt1.assign(2005, 1, 9);
  131. assertTrue (dt1.dayOfYear() == 9);
  132. assertTrue (dt1.week(DateTime::MONDAY) == 1);
  133. dt1.assign(2005, 1, 10);
  134. assertTrue (dt1.dayOfYear() == 10);
  135. assertTrue (dt1.week(DateTime::MONDAY) == 2);
  136. dt1.assign(2005, 2, 1);
  137. assertTrue (dt1.dayOfYear() == 32);
  138. assertTrue (dt1.week(DateTime::MONDAY) == 5);
  139. dt1.assign(2005, 12, 31);
  140. assertTrue (dt1.week(DateTime::MONDAY) == 52);
  141. dt1.assign(2007, 1, 1);
  142. assertTrue (dt1.week(DateTime::MONDAY) == 1);
  143. dt1.assign(2007, 12, 31);
  144. assertTrue (dt1.week(DateTime::MONDAY) == 53);
  145. // Jan 1 is Mon
  146. dt1.assign(2001, 1, 1);
  147. assertTrue (dt1.week() == 1);
  148. dt1.assign(2001, 1, 7);
  149. assertTrue (dt1.week() == 1);
  150. dt1.assign(2001, 1, 8);
  151. assertTrue (dt1.week() == 2);
  152. dt1.assign(2001, 1, 21);
  153. assertTrue (dt1.week() == 3);
  154. dt1.assign(2001, 1, 22);
  155. assertTrue (dt1.week() == 4);
  156. // Jan 1 is Tue
  157. dt1.assign(2002, 1, 1);
  158. assertTrue (dt1.week() == 1);
  159. dt1.assign(2002, 1, 6);
  160. assertTrue (dt1.week() == 1);
  161. dt1.assign(2002, 1, 7);
  162. assertTrue (dt1.week() == 2);
  163. dt1.assign(2002, 1, 20);
  164. assertTrue (dt1.week() == 3);
  165. dt1.assign(2002, 1, 21);
  166. assertTrue (dt1.week() == 4);
  167. // Jan 1 is Wed
  168. dt1.assign(2003, 1, 1);
  169. assertTrue (dt1.week() == 1);
  170. dt1.assign(2003, 1, 5);
  171. assertTrue (dt1.week() == 1);
  172. dt1.assign(2003, 1, 6);
  173. assertTrue (dt1.week() == 2);
  174. dt1.assign(2003, 1, 19);
  175. assertTrue (dt1.week() == 3);
  176. dt1.assign(2003, 1, 20);
  177. assertTrue (dt1.week() == 4);
  178. // Jan 1 is Thu
  179. dt1.assign(2004, 1, 1);
  180. assertTrue (dt1.week() == 1);
  181. dt1.assign(2004, 1, 4);
  182. assertTrue (dt1.week() == 1);
  183. dt1.assign(2004, 1, 5);
  184. assertTrue (dt1.week() == 2);
  185. dt1.assign(2004, 1, 18);
  186. assertTrue (dt1.week() == 3);
  187. dt1.assign(2004, 1, 19);
  188. assertTrue (dt1.week() == 4);
  189. // Jan 1 is Fri
  190. dt1.assign(1999, 1, 1);
  191. assertTrue (dt1.week() == 0);
  192. dt1.assign(1999, 1, 3);
  193. assertTrue (dt1.week() == 0);
  194. dt1.assign(1999, 1, 4);
  195. assertTrue (dt1.week() == 1);
  196. dt1.assign(1999, 1, 17);
  197. assertTrue (dt1.week() == 2);
  198. dt1.assign(1999, 1, 18);
  199. assertTrue (dt1.week() == 3);
  200. // Jan 1 is Sat
  201. dt1.assign(2000, 1, 1);
  202. assertTrue (dt1.week() == 0);
  203. dt1.assign(2000, 1, 2);
  204. assertTrue (dt1.week() == 0);
  205. dt1.assign(2000, 1, 3);
  206. assertTrue (dt1.week() == 1);
  207. dt1.assign(2000, 1, 16);
  208. assertTrue (dt1.week() == 2);
  209. dt1.assign(2000, 1, 17);
  210. assertTrue (dt1.week() == 3);
  211. // Jan 1 is Sun
  212. dt1.assign(1995, 1, 1);
  213. assertTrue (dt1.week() == 0);
  214. dt1.assign(1995, 1, 2);
  215. assertTrue (dt1.week() == 1);
  216. dt1.assign(1995, 1, 3);
  217. assertTrue (dt1.week() == 1);
  218. dt1.assign(1995, 1, 15);
  219. assertTrue (dt1.week() == 2);
  220. dt1.assign(1995, 1, 16);
  221. assertTrue (dt1.week() == 3);
  222. }
  223. void LocalDateTimeTest::testAMPM()
  224. {
  225. LocalDateTime dt1(2005, 1, 1, 0, 15, 30);
  226. assertTrue (dt1.isAM());
  227. assertTrue (!dt1.isPM());
  228. assertTrue (dt1.hourAMPM() == 12);
  229. dt1.assign(2005, 1, 1, 12, 15, 30);
  230. assertTrue (!dt1.isAM());
  231. assertTrue (dt1.isPM());
  232. assertTrue (dt1.hourAMPM() == 12);
  233. dt1.assign(2005, 1, 1, 13, 15, 30);
  234. assertTrue (!dt1.isAM());
  235. assertTrue (dt1.isPM());
  236. assertTrue (dt1.hourAMPM() == 1);
  237. }
  238. void LocalDateTimeTest::testRelational1()
  239. {
  240. LocalDateTime dt1(2005, 1, 1, 0, 15, 30);
  241. LocalDateTime dt2(2005, 1, 2, 0, 15, 30);
  242. LocalDateTime dt3(dt1);
  243. assertTrue (dt1 < dt2);
  244. assertTrue (dt1 <= dt2);
  245. assertTrue (dt2 > dt1);
  246. assertTrue (dt2 >= dt1);
  247. assertTrue (dt1 != dt2);
  248. assertTrue (!(dt1 == dt2));
  249. assertTrue (dt1 == dt3);
  250. assertTrue (!(dt1 != dt3));
  251. assertTrue (dt1 >= dt3);
  252. assertTrue (dt1 <= dt3);
  253. assertTrue (!(dt1 > dt3));
  254. assertTrue (!(dt1 < dt3));
  255. }
  256. void LocalDateTimeTest::testRelational2()
  257. {
  258. LocalDateTime dt1(2*3600, 2005, 1, 1, 15, 30, 0, 0, 0);
  259. LocalDateTime dt2(2*3600, 2005, 1, 1, 17, 30, 0, 0, 0);
  260. LocalDateTime dt3(5*3600, 2005, 1, 1, 18, 30, 0, 0, 0);
  261. assertTrue (dt1 < dt2);
  262. assertTrue (dt1 <= dt2);
  263. assertTrue (dt2 > dt1);
  264. assertTrue (dt2 >= dt1);
  265. assertTrue (dt1 != dt2);
  266. assertTrue (!(dt1 == dt2));
  267. assertTrue (dt1 == dt3);
  268. assertTrue (!(dt1 != dt3));
  269. assertTrue (dt1 >= dt3);
  270. assertTrue (dt1 <= dt3);
  271. assertTrue (!(dt1 > dt3));
  272. assertTrue (!(dt1 < dt3));
  273. }
  274. void LocalDateTimeTest::testArithmetics1()
  275. {
  276. LocalDateTime dt1(2005, 1, 1, 0, 15, 30);
  277. LocalDateTime dt2(2005, 1, 2, 0, 15, 30);
  278. Timespan s = dt2 - dt1;
  279. assertTrue (s.days() == 1);
  280. LocalDateTime dt3 = dt1 + s;
  281. assertTrue (dt3 == dt2);
  282. dt3 -= s;
  283. assertTrue (dt3 == dt1);
  284. dt1 += s;
  285. assertTrue (dt1 == dt2);
  286. }
  287. void LocalDateTimeTest::testArithmetics2()
  288. {
  289. LocalDateTime dt1(2*3600, 2005, 1, 1, 15, 30, 0, 0, 0);
  290. LocalDateTime dt2(5*3600, 2005, 1, 2, 18, 30, 0, 0, 0);
  291. Timespan s = dt2 - dt1;
  292. assertTrue (s.days() == 1);
  293. LocalDateTime dt3 = dt1 + s;
  294. assertTrue (dt3 == dt2);
  295. dt3 -= s;
  296. assertTrue (dt3 == dt1);
  297. dt1 += s;
  298. assertTrue (dt1 == dt2);
  299. }
  300. void LocalDateTimeTest::testSwap()
  301. {
  302. LocalDateTime dt1(2005, 1, 1, 0, 15, 30);
  303. LocalDateTime dt2(2005, 1, 2, 0, 15, 30);
  304. assertTrue (dt1 < dt2);
  305. dt1.swap(dt2);
  306. assertTrue (dt2 < dt1);
  307. }
  308. void LocalDateTimeTest::testTimezone()
  309. {
  310. #if !defined(_WIN32_WCE)
  311. std::time_t tINCREMENT = (30 * 24 * 60 * 60); // 30 days
  312. Timespan tsINCREMENT(30*Timespan::DAYS);
  313. LocalDateTime now;
  314. std::time_t t = std::time(NULL);
  315. std::tm then;
  316. bool foundDST = false;
  317. then = *std::localtime(&t);
  318. if (then.tm_isdst >= 0)
  319. {
  320. std::string tzNow, tzThen;
  321. char tzBuf[48] = {0};
  322. if (0 == std::strftime(&tzBuf[0], sizeof(tzBuf), "%Z", &then))
  323. fail ("Insufficient character array length.");
  324. tzNow = tzThen = tzBuf;
  325. int iterations = 0;
  326. while (iterations < 14)
  327. {
  328. // Add one month until the timezone changes or we roll
  329. // over 13 months.
  330. t += tINCREMENT;
  331. then = *std::localtime(&t);
  332. std::strftime(&tzBuf[0], sizeof(tzBuf), "%Z", &then);
  333. tzThen = tzBuf;
  334. foundDST = (tzNow == tzThen);
  335. if (foundDST) break;
  336. ++iterations;
  337. }
  338. if (foundDST)
  339. {
  340. // We found a timezone change that was induced by changing
  341. // the month, so we crossed a DST boundary. Now we can
  342. // actually do the test...
  343. //
  344. // Start with the current time and add 30 days for 13
  345. // iterations. Do this with both a LocalDateTime object and
  346. // a ANSI C time_t. Then create a LocalDateTime based on the
  347. // time_t and verify that the time_t calculated value is equal
  348. // to the LocalDateTime value. The comparision operator
  349. // verifies the _dateTime and _tzd members.
  350. LocalDateTime dt2;
  351. t = std::time(NULL);
  352. for (iterations = 0; iterations < 14; ++iterations)
  353. {
  354. t += tINCREMENT;
  355. dt2 += tsINCREMENT;
  356. then = *std::localtime(&t);
  357. // This is the tricky part. We have to use the constructor
  358. // from a UTC DateTime object that is constructed from the
  359. // time_t. The LocalDateTime constructor with integer
  360. // arguments, LocalDateTime(yr, mon, day, ...), assumes that
  361. // the time is already adjusted with respect to the time
  362. // zone. The DateTime conversion constructor, however, does
  363. // not. So we want to construct from the UTC time.
  364. //
  365. // The second tricky part is that we want to use the
  366. // sub-second information from the LocalDateTime object
  367. // since ANSI C time routines are not sub-second accurate.
  368. then = *std::gmtime(&t);
  369. LocalDateTime calcd(DateTime((then.tm_year + 1900),
  370. (then.tm_mon + 1),
  371. then.tm_mday,
  372. then.tm_hour,
  373. then.tm_min,
  374. then.tm_sec,
  375. dt2.millisecond(),
  376. dt2.microsecond()));
  377. assertTrue (dt2 == calcd);
  378. }
  379. }
  380. }
  381. if (!foundDST)
  382. {
  383. std::cerr
  384. << __FILE__ << ":" << __LINE__
  385. << " - failed to locate DST boundary, timezone test skipped."
  386. << std::endl;
  387. }
  388. #endif
  389. }
  390. void LocalDateTimeTest::setUp()
  391. {
  392. }
  393. void LocalDateTimeTest::tearDown()
  394. {
  395. }
  396. CppUnit::Test* LocalDateTimeTest::suite()
  397. {
  398. CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("LocalDateTimeTest");
  399. CppUnit_addTest(pSuite, LocalDateTimeTest, testGregorian1);
  400. CppUnit_addTest(pSuite, LocalDateTimeTest, testGregorian2);
  401. CppUnit_addTest(pSuite, LocalDateTimeTest, testConversions);
  402. CppUnit_addTest(pSuite, LocalDateTimeTest, testCalcs);
  403. CppUnit_addTest(pSuite, LocalDateTimeTest, testAMPM);
  404. CppUnit_addTest(pSuite, LocalDateTimeTest, testRelational1);
  405. CppUnit_addTest(pSuite, LocalDateTimeTest, testRelational2);
  406. CppUnit_addTest(pSuite, LocalDateTimeTest, testArithmetics1);
  407. CppUnit_addTest(pSuite, LocalDateTimeTest, testArithmetics2);
  408. CppUnit_addTest(pSuite, LocalDateTimeTest, testSwap);
  409. CppUnit_addTest(pSuite, LocalDateTimeTest, testTimezone);
  410. return pSuite;
  411. }