date_names_put.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
  2. #define DATE_TIME_DATE_NAMES_PUT_HPP___
  3. /* Copyright (c) 2002-2005 CrystalClear Software, Inc.
  4. * Use, modification and distribution is subject to the
  5. * Boost Software License, Version 1.0. (See accompanying
  6. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. * Author: Jeff Garland, Bart Garst
  8. * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
  9. */
  10. #include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
  11. #ifndef BOOST_DATE_TIME_NO_LOCALE
  12. #include "boost/date_time/special_defs.hpp"
  13. #include "boost/date_time/date_defs.hpp"
  14. #include "boost/date_time/parse_format_base.hpp"
  15. #include "boost/lexical_cast.hpp"
  16. #include <locale>
  17. namespace boost {
  18. namespace date_time {
  19. //! Output facet base class for gregorian dates.
  20. /*! This class is a base class for date facets used to localize the
  21. * names of months and the names of days in the week.
  22. *
  23. * Requirements of Config
  24. * - define an enumeration month_enum that enumerates the months.
  25. * The enumeration should be '1' based eg: Jan==1
  26. * - define as_short_string and as_long_string
  27. *
  28. * (see langer & kreft p334).
  29. *
  30. */
  31. template<class Config,
  32. class charT = char,
  33. class OutputIterator = std::ostreambuf_iterator<charT> >
  34. class date_names_put : public std::locale::facet
  35. {
  36. public:
  37. date_names_put() {};
  38. typedef OutputIterator iter_type;
  39. typedef typename Config::month_type month_type;
  40. typedef typename Config::month_enum month_enum;
  41. typedef typename Config::weekday_enum weekday_enum;
  42. typedef typename Config::special_value_enum special_value_enum;
  43. //typedef typename Config::format_type format_type;
  44. typedef std::basic_string<charT> string_type;
  45. typedef charT char_type;
  46. static const char_type default_special_value_names[3][17];
  47. static const char_type separator[2];
  48. static std::locale::id id;
  49. #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
  50. std::locale::id& __get_id (void) const { return id; }
  51. #endif
  52. void put_special_value(iter_type& oitr, special_value_enum sv) const
  53. {
  54. do_put_special_value(oitr, sv);
  55. }
  56. void put_month_short(iter_type& oitr, month_enum moy) const
  57. {
  58. do_put_month_short(oitr, moy);
  59. }
  60. void put_month_long(iter_type& oitr, month_enum moy) const
  61. {
  62. do_put_month_long(oitr, moy);
  63. }
  64. void put_weekday_short(iter_type& oitr, weekday_enum wd) const
  65. {
  66. do_put_weekday_short(oitr, wd);
  67. }
  68. void put_weekday_long(iter_type& oitr, weekday_enum wd) const
  69. {
  70. do_put_weekday_long(oitr, wd);
  71. }
  72. bool has_date_sep_chars() const
  73. {
  74. return do_has_date_sep_chars();
  75. }
  76. void year_sep_char(iter_type& oitr) const
  77. {
  78. do_year_sep_char(oitr);
  79. }
  80. //! char between year-month
  81. void month_sep_char(iter_type& oitr) const
  82. {
  83. do_month_sep_char(oitr);
  84. }
  85. //! Char to separate month-day
  86. void day_sep_char(iter_type& oitr) const
  87. {
  88. do_day_sep_char(oitr);
  89. }
  90. //! Determines the order to put the date elements
  91. ymd_order_spec date_order() const
  92. {
  93. return do_date_order();
  94. }
  95. //! Determines if month is displayed as integer, short or long string
  96. month_format_spec month_format() const
  97. {
  98. return do_month_format();
  99. }
  100. protected:
  101. //! Default facet implementation uses month_type defaults
  102. virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
  103. {
  104. month_type gm(moy);
  105. charT c = '\0';
  106. put_string(oitr, gm.as_short_string(c));
  107. }
  108. //! Default facet implementation uses month_type defaults
  109. virtual void do_put_month_long(iter_type& oitr,
  110. month_enum moy) const
  111. {
  112. month_type gm(moy);
  113. charT c = '\0';
  114. put_string(oitr, gm.as_long_string(c));
  115. }
  116. //! Default facet implementation for special value types
  117. virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
  118. {
  119. if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
  120. string_type s(default_special_value_names[sv]);
  121. put_string(oitr, s);
  122. }
  123. }
  124. virtual void do_put_weekday_short(iter_type&, weekday_enum) const
  125. {
  126. }
  127. virtual void do_put_weekday_long(iter_type&, weekday_enum) const
  128. {
  129. }
  130. virtual bool do_has_date_sep_chars() const
  131. {
  132. return true;
  133. }
  134. virtual void do_year_sep_char(iter_type& oitr) const
  135. {
  136. string_type s(separator);
  137. put_string(oitr, s);
  138. }
  139. //! char between year-month
  140. virtual void do_month_sep_char(iter_type& oitr) const
  141. {
  142. string_type s(separator);
  143. put_string(oitr, s);
  144. }
  145. //! Char to separate month-day
  146. virtual void do_day_sep_char(iter_type& oitr) const
  147. {
  148. string_type s(separator); //put in '-'
  149. put_string(oitr, s);
  150. }
  151. //! Default for date order
  152. virtual ymd_order_spec do_date_order() const
  153. {
  154. return ymd_order_iso;
  155. }
  156. //! Default month format
  157. virtual month_format_spec do_month_format() const
  158. {
  159. return month_as_short_string;
  160. }
  161. void put_string(iter_type& oi, const charT* const s) const
  162. {
  163. string_type s1(boost::lexical_cast<string_type>(s));
  164. typename string_type::iterator si,end;
  165. for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
  166. *oi = *si;
  167. }
  168. }
  169. void put_string(iter_type& oi, const string_type& s1) const
  170. {
  171. typename string_type::const_iterator si,end;
  172. for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
  173. *oi = *si;
  174. }
  175. }
  176. };
  177. template<class Config, class charT, class OutputIterator>
  178. const typename date_names_put<Config, charT, OutputIterator>::char_type
  179. date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = {
  180. {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
  181. {'-','i','n','f','i','n','i','t','y'},
  182. {'+','i','n','f','i','n','i','t','y'} };
  183. template<class Config, class charT, class OutputIterator>
  184. const typename date_names_put<Config, charT, OutputIterator>::char_type
  185. date_names_put<Config, charT, OutputIterator>::separator[2] =
  186. {'-', '\0'} ;
  187. //! Generate storage location for a std::locale::id
  188. template<class Config, class charT, class OutputIterator>
  189. std::locale::id date_names_put<Config, charT, OutputIterator>::id;
  190. //! A date name output facet that takes an array of char* to define strings
  191. template<class Config,
  192. class charT = char,
  193. class OutputIterator = std::ostreambuf_iterator<charT> >
  194. class all_date_names_put : public date_names_put<Config, charT, OutputIterator>
  195. {
  196. public:
  197. all_date_names_put(const charT* const month_short_names[],
  198. const charT* const month_long_names[],
  199. const charT* const special_value_names[],
  200. const charT* const weekday_short_names[],
  201. const charT* const weekday_long_names[],
  202. charT separator_char = '-',
  203. ymd_order_spec order_spec = ymd_order_iso,
  204. month_format_spec month_format = month_as_short_string) :
  205. month_short_names_(month_short_names),
  206. month_long_names_(month_long_names),
  207. special_value_names_(special_value_names),
  208. weekday_short_names_(weekday_short_names),
  209. weekday_long_names_(weekday_long_names),
  210. order_spec_(order_spec),
  211. month_format_spec_(month_format)
  212. {
  213. separator_char_[0] = separator_char;
  214. separator_char_[1] = '\0';
  215. };
  216. typedef OutputIterator iter_type;
  217. typedef typename Config::month_enum month_enum;
  218. typedef typename Config::weekday_enum weekday_enum;
  219. typedef typename Config::special_value_enum special_value_enum;
  220. const charT* const* get_short_month_names() const
  221. {
  222. return month_short_names_;
  223. }
  224. const charT* const* get_long_month_names() const
  225. {
  226. return month_long_names_;
  227. }
  228. const charT* const* get_special_value_names() const
  229. {
  230. return special_value_names_;
  231. }
  232. const charT* const* get_short_weekday_names()const
  233. {
  234. return weekday_short_names_;
  235. }
  236. const charT* const* get_long_weekday_names()const
  237. {
  238. return weekday_long_names_;
  239. }
  240. protected:
  241. //! Generic facet that takes array of chars
  242. virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
  243. {
  244. this->put_string(oitr, month_short_names_[moy-1]);
  245. }
  246. //! Long month names
  247. virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
  248. {
  249. this->put_string(oitr, month_long_names_[moy-1]);
  250. }
  251. //! Special values names
  252. virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
  253. {
  254. this->put_string(oitr, special_value_names_[sv]);
  255. }
  256. virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
  257. {
  258. this->put_string(oitr, weekday_short_names_[wd]);
  259. }
  260. virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
  261. {
  262. this->put_string(oitr, weekday_long_names_[wd]);
  263. }
  264. //! char between year-month
  265. virtual void do_month_sep_char(iter_type& oitr) const
  266. {
  267. this->put_string(oitr, separator_char_);
  268. }
  269. //! Char to separate month-day
  270. virtual void do_day_sep_char(iter_type& oitr) const
  271. {
  272. this->put_string(oitr, separator_char_);
  273. }
  274. //! Set the date ordering
  275. virtual ymd_order_spec do_date_order() const
  276. {
  277. return order_spec_;
  278. }
  279. //! Set the date ordering
  280. virtual month_format_spec do_month_format() const
  281. {
  282. return month_format_spec_;
  283. }
  284. private:
  285. const charT* const* month_short_names_;
  286. const charT* const* month_long_names_;
  287. const charT* const* special_value_names_;
  288. const charT* const* weekday_short_names_;
  289. const charT* const* weekday_long_names_;
  290. charT separator_char_[2];
  291. ymd_order_spec order_spec_;
  292. month_format_spec month_format_spec_;
  293. };
  294. } } //namespace boost::date_time
  295. #endif //BOOST_NO_STD_LOCALE
  296. #endif