1 #ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___
2 #define DATE_TIME_STRINGS_FROM_FACET__HPP___
3 
4 /* Copyright (c) 2004 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
9  * $Date$
10  */
11 
12 #include <cstring>
13 #include <sstream>
14 #include <string>
15 #include <vector>
16 #include <locale>
17 #include <iterator>
18 
19 namespace boost { namespace date_time {
20 
21 //! This function gathers up all the month strings from a std::locale
22 /*! Using the time_put facet, this function creates a collection of
23  *  all the month strings from a locale.  This is handy when building
24  *  custom date parsers or formatters that need to be localized.
25  *
26  *@param charT The type of char to use when gathering typically char
27  *             or wchar_t.
28  *@param locale The locale to use when gathering the strings
29  *@param short_strings True(default) to gather short strings,
30  *                     false for long strings.
31  *@return A vector of strings containing the strings in order. eg:
32  *        Jan, Feb, Mar, etc.
33  */
34 template<typename charT>
35 std::vector<std::basic_string<charT> >
gather_month_strings(const std::locale & locale,bool short_strings=true)36 gather_month_strings(const std::locale& locale, bool short_strings=true)
37 {
38   typedef std::basic_string<charT> string_type;
39   typedef std::vector<string_type> collection_type;
40   typedef std::ostreambuf_iterator<charT> ostream_iter_type;
41   typedef std::basic_ostringstream<charT> stringstream_type;
42   typedef std::time_put<charT>           time_put_facet_type;
43   charT short_fmt[3] = { '%', 'b' };
44   charT long_fmt[3]  = { '%', 'B' };
45   collection_type months;
46   string_type outfmt(short_fmt);
47   if (!short_strings) {
48     outfmt = long_fmt;
49   }
50   {
51     //grab the needed strings by using the locale to
52     //output each month
53     const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
54     tm tm_value;
55     std::memset(&tm_value, 0, sizeof(tm_value));
56     for (int m=0; m < 12; m++) {
57       tm_value.tm_mon = m;
58       stringstream_type ss;
59       ostream_iter_type oitr(ss);
60       std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
61                                                       &tm_value,
62                                                       p_outfmt,
63                                                       p_outfmt_end);
64       months.push_back(ss.str());
65     }
66   }
67   return months;
68 }
69 
70 //! This function gathers up all the weekday strings from a std::locale
71 /*! Using the time_put facet, this function creates a collection of
72  *  all the weekday strings from a locale starting with the string for
73  *  'Sunday'.  This is handy when building custom date parsers or
74  *  formatters that need to be localized.
75  *
76  *@param charT The type of char to use when gathering typically char
77  *             or wchar_t.
78  *@param locale The locale to use when gathering the strings
79  *@param short_strings True(default) to gather short strings,
80  *                     false for long strings.
81  *@return A vector of strings containing the weekdays in order. eg:
82  *        Sun, Mon, Tue, Wed, Thu, Fri, Sat
83  */
84 template<typename charT>
85 std::vector<std::basic_string<charT> >
gather_weekday_strings(const std::locale & locale,bool short_strings=true)86 gather_weekday_strings(const std::locale& locale, bool short_strings=true)
87 {
88   typedef std::basic_string<charT> string_type;
89   typedef std::vector<string_type> collection_type;
90   typedef std::ostreambuf_iterator<charT> ostream_iter_type;
91   typedef std::basic_ostringstream<charT> stringstream_type;
92   typedef std::time_put<charT>           time_put_facet_type;
93   charT short_fmt[3] = { '%', 'a' };
94   charT long_fmt[3]  = { '%', 'A' };
95 
96   collection_type weekdays;
97 
98 
99   string_type outfmt(short_fmt);
100   if (!short_strings) {
101     outfmt = long_fmt;
102   }
103   {
104     //grab the needed strings by using the locale to
105     //output each month / weekday
106     const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
107     tm tm_value;
108     std::memset(&tm_value, 0, sizeof(tm_value));
109     for (int i=0; i < 7; i++) {
110       tm_value.tm_wday = i;
111       stringstream_type ss;
112       ostream_iter_type oitr(ss);
113       std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
114                                                       &tm_value,
115                                                       p_outfmt,
116                                                       p_outfmt_end);
117 
118       weekdays.push_back(ss.str());
119     }
120   }
121   return weekdays;
122 }
123 
124 } } //namespace
125 
126 
127 #endif
128