testformat_date_parser.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /* Copyright (c) 2004 CrystalClear Software, Inc.
  2. * Use, modification and distribution is subject to the
  3. * Boost Software License, Version 1.0. (See accompanying
  4. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  5. * Author: Jeff Garland
  6. */
  7. #include "boost/date_time/gregorian/gregorian.hpp"
  8. #include "../testfrmwk.hpp"
  9. #include "boost/date_time/format_date_parser.hpp"
  10. #include <sstream>
  11. #include <algorithm>
  12. #include <iostream>
  13. const wchar_t* const wmonth_short_names[]={L"Jan",L"Feb",L"Mar",
  14. L"Apr",L"May",L"Jun",
  15. L"Jul",L"Aug",L"Sep",
  16. L"Oct",L"Nov",L"Dec"};
  17. const char* const month_short_names[]={"Jan","Feb","Mar",
  18. "Apr","May","Jun",
  19. "Jul","Aug","Sep",
  20. "Oct","Nov","Dec"};
  21. const char* const month_long_names[]={"January","February","March",
  22. "April","May","June",
  23. "July","August","September",
  24. "October","November","December"};
  25. const wchar_t* const wmonth_long_names[]={L"January",L"February",L"March",
  26. L"April",L"May",L"June",
  27. L"July",L"August",L"September",
  28. L"October",L"Novomber",L"December"};
  29. const wchar_t* const wweek_short_names[]= {L"Sun", L"Mon", L"Tue", L"Wed",
  30. L"Thu", L"Fri", L"Sat"};
  31. const char* const week_short_names[]={"Sun", "Mon","Tue","Wed",
  32. "Thu","Fri","Sat"};
  33. const wchar_t* const wweek_long_names[]= {L"Sunday", L"Monday", L"Tuesday",
  34. L"Wednesday", L"Thursday",
  35. L"Friday", L"Saturday"};
  36. const char* const week_long_names[]= {"Sunday", "Monday", "Tuesday",
  37. "Wednesday", "Thursday",
  38. "Friday", "Saturday"};
  39. std::vector<std::basic_string<char> > short_month_names;
  40. std::vector<std::basic_string<wchar_t> > wshort_month_names;
  41. std::vector<std::basic_string<char> > long_month_names;
  42. std::vector<std::basic_string<wchar_t> > wlong_month_names;
  43. std::vector<std::basic_string<char> > short_week_names;
  44. std::vector<std::basic_string<wchar_t> > wshort_week_names;
  45. std::vector<std::basic_string<char> > long_week_names;
  46. std::vector<std::basic_string<wchar_t> > wlong_week_names;
  47. using namespace boost::gregorian;
  48. void
  49. wtest_format(const std::basic_string<wchar_t>& format,
  50. const std::basic_string<wchar_t>& value,
  51. const std::string& testname,
  52. boost::gregorian::date expected_res)
  53. {
  54. typedef boost::date_time::format_date_parser<date, wchar_t> parser_type;
  55. typedef std::basic_string<wchar_t> string_type;
  56. typedef std::istreambuf_iterator<wchar_t> iter_type;
  57. try {
  58. // string_type format(format);
  59. std::basic_stringstream<wchar_t> ws;
  60. ws << value;
  61. iter_type sitr(ws);
  62. iter_type stream_end;
  63. parser_type p(format, wshort_month_names, wlong_month_names,
  64. wshort_week_names, wlong_week_names);
  65. date d = p.parse_date(sitr, stream_end, format);
  66. check_equal(testname, d, expected_res);
  67. }
  68. catch(std::exception& e) {
  69. std::cout << "Got an exception: " << e.what() << std::endl;
  70. check(testname, false);
  71. }
  72. }
  73. void
  74. test_format(const std::basic_string<char>& format,
  75. const std::basic_string<char>& value,
  76. const std::string& testname,
  77. boost::gregorian::date expected_res)
  78. {
  79. typedef boost::date_time::format_date_parser<date, char> parser_type;
  80. typedef std::basic_string<char> string_type;
  81. typedef std::istreambuf_iterator<char> iter_type;
  82. try {
  83. string_type format(format);
  84. std::basic_stringstream<char> ws;
  85. ws << value;
  86. iter_type sitr(ws);
  87. iter_type stream_end;
  88. parser_type pt(format, short_month_names, long_month_names,
  89. short_week_names, long_week_names);
  90. date d = pt.parse_date(sitr, stream_end, format);
  91. check_equal(testname, d, expected_res);
  92. }
  93. catch(std::exception& e) {
  94. std::cout << "Got an exception: " << e.what() << std::endl;
  95. check(testname, false);
  96. }
  97. }
  98. template<typename charT>
  99. void
  100. test_format2(boost::date_time::format_date_parser<date, charT>& parser,
  101. const charT* const format,
  102. const charT* const value,
  103. const std::string& testname,
  104. boost::gregorian::date expected_res)
  105. {
  106. try {
  107. date d = parser.parse_date(value, format);
  108. check_equal(testname, d == expected_res);
  109. }
  110. catch(std::exception& e) {
  111. std::cout << "Got an exception: " << e.what() << std::endl;
  112. check(testname, false);
  113. }
  114. }
  115. int
  116. main()
  117. {
  118. std::copy(&wmonth_short_names[0],
  119. &wmonth_short_names[12],
  120. std::back_inserter(wshort_month_names));
  121. std::copy(&month_short_names[0],
  122. &month_short_names[12],
  123. std::back_inserter(short_month_names));
  124. std::copy(&month_long_names[0],
  125. &month_long_names[12],
  126. std::back_inserter(long_month_names));
  127. std::copy(&wmonth_long_names[0],
  128. &wmonth_long_names[12],
  129. std::back_inserter(wlong_month_names));
  130. std::copy(&wweek_short_names[0],
  131. &wweek_short_names[7],
  132. std::back_inserter(wshort_week_names));
  133. std::copy(&week_short_names[0],
  134. &week_short_names[7],
  135. std::back_inserter(short_week_names));
  136. std::copy(&wweek_long_names[0],
  137. &wweek_long_names[7],
  138. std::back_inserter(wlong_week_names));
  139. std::copy(&week_long_names[0],
  140. &week_long_names[7],
  141. std::back_inserter(long_week_names));
  142. wtest_format(L"1%%23%Y %m %d", L"1232004 12 31 other stuff...",
  143. "wide and weird", date(2004,12,31));
  144. wtest_format(L"%Y-%m-%d", L"2004-12-31",
  145. "%Y-%m-%d wide", date(2004,12,31));
  146. wtest_format(L"%Y day %j", L"2004 day 001",
  147. "%Y day %j wide", date(2004,1,1));
  148. test_format("%m/%d/%y", "10/31/04",
  149. "%m/%d/%y", date(2004,10,31));
  150. wtest_format(L"%Y/%m/%d", L"2004-12-31",
  151. "%Y/%m/%d wide 2004-12-31 input", date(2004,12,31));
  152. test_format("%Y.%d.%m", "2004.31.1",
  153. "%Y.%d.%m var length", date(2004,Jan,31));
  154. test_format("%d.%m.%Y", "1.1.2004",
  155. "%d.%m.%Y var length month and day", date(2004,1,1));
  156. test_format("%Y.%m.%d", "2004.1.31",
  157. "%Y.%m.%d var length month", date(2004,Jan,31));
  158. test_format("%Y.%b.%d", "2004.Jan.1",
  159. "%Y.%b.%d var length month", date(2004,Jan,1));
  160. test_format("%Y%m%d", "20041231",
  161. "%Y%m%d undelimited", date(2004,12,31));
  162. test_format("%Y/%d/%b", "2004/01/Jan",
  163. "%Y/%d/%b month at end", date(2004,1,1));
  164. test_format("%Y/%b/%d", "2004/Jan/01",
  165. "%Y/%b/%d named month jan", date(2004,1,1));
  166. test_format("%Y/%b/%d", "2004/Dec/20",
  167. "%Y/%b/%d named month dec", date(2004,12,20));
  168. wtest_format(L"%Y/%b/%d", L"2004-Jul-31",
  169. "%Y/%b/%d wide 2004-Jul-31 input", date(2004,7,31));
  170. wtest_format(L"%B %d, %Y", L"March 15, 2004",
  171. "%B %d, %Y", date(2004,3,15));
  172. wtest_format(L"%a %B %d, %Y", L"Sun March 15, 2004",
  173. "%a %B %d, %Y", date(2004,3,15));
  174. wtest_format(L"%A %B %d, %Y", L"Sunday March 15, 2004",
  175. "%A %B %d, %Y", date(2004,3,15));
  176. // bad format case...
  177. {
  178. try {
  179. std::wstring format(L"%Y-%d");
  180. std::wstringstream ws;
  181. ws << L"2004-12-31";
  182. std::istreambuf_iterator<wchar_t> sitr(ws);
  183. std::istreambuf_iterator<wchar_t> stream_end;
  184. boost::date_time::format_date_parser<date,wchar_t> pt(format,
  185. wshort_month_names,
  186. wlong_month_names,
  187. wshort_week_names,
  188. wlong_week_names);
  189. date d = pt.parse_date(sitr, stream_end);
  190. check("Bad format spec test", false);
  191. }
  192. catch(std::exception& e) {
  193. std::cout << "Got an expected exception: " << e.what() << std::endl;
  194. check("Bad format spec test -- pass", true);
  195. }
  196. }
  197. {
  198. //some interesting month names
  199. const char* const roman_months[]={"I","II","III",
  200. "IV","V","VI",
  201. "VII","VIII","IX",
  202. "X","XI","XII"};
  203. std::vector<std::basic_string<char> > roman_month_names;
  204. std::copy(&roman_months[0],
  205. &roman_months[12],
  206. std::back_inserter(roman_month_names));
  207. std::string format("%Y.%b.%d");
  208. boost::date_time::format_date_parser<date,char> parser(format,
  209. roman_month_names,
  210. long_month_names,
  211. short_week_names,
  212. long_week_names);
  213. test_format2(parser, "%Y.%b.%d", "2004-I-1",
  214. "roman I", date(2004,Jan,1));
  215. test_format2(parser, "%Y.%b.%d", "2004-II-01",
  216. "roman II", date(2004,Feb,1));
  217. test_format2(parser, "%Y.%b.%d", "2004-III-01",
  218. "roman III", date(2004,Mar,1));
  219. test_format2(parser, "%Y.%b.%d", "2004-IV-01",
  220. "roman IV", date(2004,Apr,1));
  221. test_format2(parser, "%Y.%b.%d", "2004-V-01",
  222. "roman V", date(2004,May,1));
  223. test_format2(parser, "%Y.%b.%d", "2004-VI-01",
  224. "roman VI", date(2004,Jun,1));
  225. test_format2(parser, "%Y.%b.%d", "2004-VII-01",
  226. "roman VII", date(2004,Jul,1));
  227. test_format2(parser, "%Y.%b.%d", "2004-VIII-01",
  228. "roman VIII", date(2004,Aug,1));
  229. test_format2(parser, "%Y.%b.%d", "2004-IX-01",
  230. "roman IX", date(2004,Sep,1));
  231. test_format2(parser, "%Y.%b.%d", "2004-X-01",
  232. "roman X", date(2004,Oct,1));
  233. test_format2(parser, "%Y.%b.%d", "2004-XI-01",
  234. "roman XI", date(2004,Nov,1));
  235. test_format2(parser, "%Y.%b.%d", "2004 XII 1",
  236. "roman XII", date(2004,Dec,1));
  237. }
  238. {
  239. //alternate constructor that takes month/weekday strings
  240. //from a locale
  241. std::string format("%Y %m %d");
  242. boost::date_time::format_date_parser<date,char> parser(format,
  243. std::locale::classic());
  244. test_format2(parser, "%a %Y.%b.%d", "Sun 2004 Jan 1",
  245. "strings from locale", date(2004,Jan,1));
  246. test_format2(parser, "%a %Y.%b.%d", "Mon 2004 Feb 1",
  247. "strings from locale", date(2004,Feb,1));
  248. test_format2(parser, "%a %Y.%b.%d", "Tue 2004 Mar 1",
  249. "strings from locale", date(2004,Mar,1));
  250. test_format2(parser, "%a %Y.%b.%d", "Wed 2004 Apr 1",
  251. "strings from locale", date(2004,Apr,1));
  252. test_format2(parser, "%a %Y.%b.%d", "thu 2004 May 1",
  253. "strings from locale", date(2004,May,1));
  254. test_format2(parser, "%a %Y.%b.%d", "fri 2004 Jun 1",
  255. "strings from locale", date(2004,Jun,1));
  256. test_format2(parser, "%a %Y.%b.%d", "sat 2004 Jul 1",
  257. "strings from locale", date(2004,Jul,1));
  258. test_format2(parser, "%Y.%b.%d", "2004 Aug 1",
  259. "strings from locale", date(2004,Aug,1));
  260. test_format2(parser, "%Y.%b.%d", "2004 Sep 1",
  261. "strings from locale", date(2004,Sep,1));
  262. test_format2(parser, "%Y.%b.%d", "2004 Sep 1",
  263. "strings from locale", date(2004,Sep,1));
  264. test_format2(parser, "%Y.%b.%d", "2004 Oct 1",
  265. "strings from locale", date(2004,Oct,1));
  266. test_format2(parser, "%Y.%b.%d", "2004 Nov 1",
  267. "strings from locale", date(2004,Nov,1));
  268. test_format2(parser, "%Y.%b.%d", "2004 Dec 1",
  269. "strings from locale", date(2004,Dec,1));
  270. test_format2(parser, "%A %B %d, %Y", "Sunday January 1, 2004",
  271. "long strings from locale", date(2004,Jan,1));
  272. test_format2(parser, "%A %B %d, %Y", "Monday February 29, 2004",
  273. "long strings from locale", date(2004,Feb,29));
  274. test_format2(parser, "%A %B %d, %Y", "Tuesday March 1, 2004",
  275. "long strings from locale", date(2004,Mar,1));
  276. test_format2(parser, "%A %B %d, %Y", "Wednesday APRIL 1, 2004",
  277. "long strings from locale", date(2004,Apr,1));
  278. test_format2(parser, "%A %B %d, %Y", "thursday may 15, 2004",
  279. "long strings from locale", date(2004,May,15));
  280. test_format2(parser, "%A %B %d, %Y", "friday june 15, 2004",
  281. "long strings from locale", date(2004,Jun,15));
  282. test_format2(parser, "%A %B %d, %Y", "saturday july 30, 2004",
  283. "long strings from locale", date(2004,Jul,30));
  284. test_format2(parser, "%A %B %d, %Y", "thursday auguST 15, 2004",
  285. "long strings from locale", date(2004,Aug,15));
  286. test_format2(parser, "%A %B %d, %Y", "thursday september 1, 2004",
  287. "long strings from locale", date(2004,Sep,1));
  288. test_format2(parser, "%A %B %d, %Y", "thursday october 1, 2004",
  289. "long strings from locale", date(2004,Oct,1));
  290. test_format2(parser, "%A %B %d, %Y", "thursday november 1, 2004",
  291. "long strings from locale", date(2004,Nov,1));
  292. test_format2(parser, "%A %B %d, %Y", "thursday december 31, 2004",
  293. "long strings from locale", date(2004,Dec,31));
  294. }
  295. return printTestStats();
  296. }