1 #ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
2 #define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
3 
4 /* Copyright (c) 2002,2003 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$
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/iso_format.hpp"
18 #include "boost/date_time/date_names_put.hpp"
19 #include "boost/date_time/parse_format_base.hpp"
20 //#include <string>
21 #include <sstream>
22 #include <iomanip>
23 
24 
25 namespace boost {
26 namespace date_time {
27 
28   //! Formats a month as as string into an ostream
29   template<class facet_type,
30            class charT = char>
31   class ostream_month_formatter
32   {
33   public:
34     typedef typename facet_type::month_type month_type;
35     typedef std::basic_ostream<charT> ostream_type;
36 
37     //! Formats a month as as string into an output iterator
format_month(const month_type & month,ostream_type & os,const facet_type & f)38     static void format_month(const month_type& month,
39                              ostream_type& os,
40                              const facet_type& f)
41     {
42 
43       switch (f.month_format())
44       {
45         case month_as_short_string:
46         {
47           std::ostreambuf_iterator<charT> oitr(os);
48           f.put_month_short(oitr, month.as_enum());
49           break;
50         }
51         case month_as_long_string:
52         {
53           std::ostreambuf_iterator<charT> oitr(os);
54           f.put_month_long(oitr, month.as_enum());
55           break;
56         }
57         case month_as_integer:
58         {
59           charT fill_char = '0';
60           os << std::setw(2) << std::setfill(fill_char) << month.as_number();
61           break;
62         }
63 
64       }
65     } // format_month
66 
67   };
68 
69 
70   //! Formats a weekday
71   template<class weekday_type,
72            class facet_type,
73            class charT = char>
74   class ostream_weekday_formatter
75   {
76   public:
77     typedef typename facet_type::month_type month_type;
78     typedef std::basic_ostream<charT> ostream_type;
79 
80     //! Formats a month as as string into an output iterator
format_weekday(const weekday_type & wd,ostream_type & os,const facet_type & f,bool as_long_string)81     static void format_weekday(const weekday_type& wd,
82                                ostream_type& os,
83                                const facet_type& f,
84                                bool  as_long_string)
85     {
86 
87       std::ostreambuf_iterator<charT> oitr(os);
88       if (as_long_string) {
89         f.put_weekday_long(oitr, wd.as_enum());
90       }
91       else {
92         f.put_weekday_short(oitr, wd.as_enum());
93       }
94 
95     } // format_weekday
96 
97   };
98 
99 
100   //! Convert ymd to a standard string formatting policies
101   template<class ymd_type,
102            class facet_type,
103            class charT = char>
104   class ostream_ymd_formatter
105   {
106   public:
107     typedef typename ymd_type::month_type month_type;
108     typedef ostream_month_formatter<facet_type, charT> month_formatter_type;
109     typedef std::basic_ostream<charT> ostream_type;
110     typedef std::basic_string<charT> foo_type;
111 
112     //! Convert ymd to a standard string formatting policies
113     /*! This is standard code for handling date formatting with
114      *  year-month-day based date information.  This function
115      *  uses the format_type to control whether the string will
116      *  contain separator characters, and if so what the character
117      *  will be.  In addtion, it can format the month as either
118      *  an integer or a string as controled by the formatting
119      *  policy
120      */
121     //     static string_type ymd_to_string(ymd_type ymd)
122 //     {
123 //       std::ostringstream ss;
124 //       facet_type dnp;
125 //       ymd_put(ymd, ss, dnp);
126 //       return ss.str();
127 //       }
128 
129 
130     // Put ymd to ostream -- part of ostream refactor
ymd_put(ymd_type ymd,ostream_type & os,const facet_type & f)131     static void ymd_put(ymd_type ymd,
132                         ostream_type& os,
133                         const facet_type& f)
134     {
135       std::ostreambuf_iterator<charT> oitr(os);
136       charT fill_char = '0';
137       switch (f.date_order()) {
138         case ymd_order_iso: {
139           os << ymd.year;
140           if (f.has_date_sep_chars()) {
141             f.month_sep_char(oitr);
142           }
143           month_formatter_type::format_month(ymd.month, os, f);
144           if (f.has_date_sep_chars()) {
145             f.day_sep_char(oitr);
146           }
147           os  << std::setw(2) << std::setfill(fill_char)
148               << ymd.day;
149           break;
150         }
151         case ymd_order_us: {
152           month_formatter_type::format_month(ymd.month, os, f);
153           if (f.has_date_sep_chars()) {
154           f.day_sep_char(oitr);
155           }
156           os  << std::setw(2) << std::setfill(fill_char)
157             << ymd.day;
158           if (f.has_date_sep_chars()) {
159             f.month_sep_char(oitr);
160           }
161           os << ymd.year;
162           break;
163         }
164         case ymd_order_dmy: {
165           os  << std::setw(2) << std::setfill(fill_char)
166               << ymd.day;
167           if (f.has_date_sep_chars()) {
168             f.day_sep_char(oitr);
169           }
170           month_formatter_type::format_month(ymd.month, os, f);
171           if (f.has_date_sep_chars()) {
172             f.month_sep_char(oitr);
173           }
174           os << ymd.year;
175           break;
176         }
177       }
178     }
179   };
180 
181 
182   //! Convert a date to string using format policies
183   template<class date_type,
184            class facet_type,
185            class charT = char>
186   class ostream_date_formatter
187   {
188   public:
189     typedef std::basic_ostream<charT> ostream_type;
190     typedef typename date_type::ymd_type ymd_type;
191 
192     //! Put date into an ostream
date_put(const date_type & d,ostream_type & os,const facet_type & f)193     static void date_put(const date_type& d,
194                          ostream_type& os,
195                          const facet_type& f)
196     {
197       special_values sv = d.as_special();
198       if (sv == not_special) {
199         ymd_type ymd = d.year_month_day();
200         ostream_ymd_formatter<ymd_type, facet_type, charT>::ymd_put(ymd, os, f);
201       }
202       else { // output a special value
203         std::ostreambuf_iterator<charT> coi(os);
204         f.put_special_value(coi, sv);
205       }
206     }
207 
208 
209     //! Put date into an ostream
date_put(const date_type & d,ostream_type & os)210     static void date_put(const date_type& d,
211                          ostream_type& os)
212     {
213       //retrieve the local from the ostream
214       std::locale locale = os.getloc();
215       if (std::has_facet<facet_type>(locale)) {
216         const facet_type& f = std::use_facet<facet_type>(locale);
217         date_put(d, os, f);
218       }
219       else {
220         //default to something sensible if no facet installed
221         facet_type default_facet;
222         date_put(d, os, default_facet);
223       }
224     } // date_to_ostream
225   }; //class date_formatter
226 
227 
228 } } //namespace date_time
229 
230 #endif
231 
232 #endif
233 
234