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