Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
Chris@16
|
3 //
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 #ifndef BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED
|
Chris@16
|
9 #define BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/locale/config.hpp>
|
Chris@16
|
12 #ifdef BOOST_MSVC
|
Chris@16
|
13 # pragma warning(push)
|
Chris@16
|
14 # pragma warning(disable : 4275 4251 4231 4660)
|
Chris@16
|
15 #endif
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/cstdint.hpp>
|
Chris@16
|
18 #include <locale>
|
Chris@16
|
19
|
Chris@16
|
20 namespace boost {
|
Chris@16
|
21 namespace locale {
|
Chris@16
|
22 ///
|
Chris@16
|
23 /// \brief Namespace that contains various types for manipulation with dates
|
Chris@16
|
24 ///
|
Chris@16
|
25 namespace period {
|
Chris@16
|
26 ///
|
Chris@16
|
27 /// \brief This namespace holds a enum of various period types like era, year, month, etc..
|
Chris@16
|
28 ///
|
Chris@16
|
29 namespace marks {
|
Chris@16
|
30 /// \brief the type that defines a flag that holds a period identifier
|
Chris@16
|
31 enum period_mark {
|
Chris@16
|
32 invalid, ///< Special invalid value, should not be used directly
|
Chris@16
|
33 era, ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1]
|
Chris@16
|
34 year, ///< Year, it is calendar specific, for example 2011 in Gregorian calendar.
|
Chris@16
|
35 extended_year, ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
|
Chris@16
|
36 month, ///< The month of year, calendar specific, in Gregorian [0..11]
|
Chris@16
|
37 day, ///< The day of month, calendar specific, in Gregorian [1..31]
|
Chris@16
|
38 day_of_year, ///< The number of day in year, starting from 1, in Gregorian [1..366]
|
Chris@16
|
39 day_of_week, ///< Day of week, Sunday=1, Monday=2,..., Saturday=7.
|
Chris@16
|
40 ///< Note that updating this value respects local day of week, so for example,
|
Chris@16
|
41 ///< If first day of week is Monday and the current day is Tuesday then setting
|
Chris@16
|
42 ///< the value to Sunday (1) would forward the date by 5 days forward and not backward
|
Chris@16
|
43 ///< by two days as it could be expected if the numbers were taken as is.
|
Chris@16
|
44 day_of_week_in_month, ///< Original number of the day of the week in month. For example 1st Sunday,
|
Chris@16
|
45 ///< 2nd Sunday, etc. in Gregorian [1..5]
|
Chris@16
|
46 day_of_week_local, ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
|
Chris@16
|
47 hour, ///< 24 clock hour [0..23]
|
Chris@16
|
48 hour_12, ///< 12 clock hour [0..11]
|
Chris@16
|
49 am_pm, ///< am or pm marker [0..1]
|
Chris@16
|
50 minute, ///< minute [0..59]
|
Chris@16
|
51 second, ///< second [0..59]
|
Chris@16
|
52 week_of_year, ///< The week number in the year
|
Chris@16
|
53 week_of_month, ///< The week number within current month
|
Chris@16
|
54 first_day_of_week, ///< First day of week, constant, for example Sunday in US = 1, Monday in France = 2
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 } // marks
|
Chris@16
|
58
|
Chris@16
|
59 ///
|
Chris@16
|
60 /// \brief This class holds a type that represents certain period of time like
|
Chris@16
|
61 /// year, hour, second and so on.
|
Chris@16
|
62 ///
|
Chris@16
|
63 /// It can be created from either marks::period_mark type or by using shortcuts in period
|
Chris@16
|
64 /// namespace - calling functions like period::year(), period::hour() and so on.
|
Chris@16
|
65 ///
|
Chris@16
|
66 /// Basically it represents the same object as enum marks::period_mark but allows to
|
Chris@16
|
67 /// provide save operator overloading that would not collide with casing of enum to
|
Chris@16
|
68 /// numeric values.
|
Chris@16
|
69 ///
|
Chris@16
|
70 class period_type {
|
Chris@16
|
71 public:
|
Chris@16
|
72 ///
|
Chris@16
|
73 /// Create a period of specific type, default is invalid.
|
Chris@16
|
74 ///
|
Chris@16
|
75 period_type(marks::period_mark m = marks::invalid) : mark_(m)
|
Chris@16
|
76 {
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 ///
|
Chris@16
|
80 /// Get the value of marks::period_mark it was created with.
|
Chris@16
|
81 ///
|
Chris@16
|
82 marks::period_mark mark() const
|
Chris@16
|
83 {
|
Chris@16
|
84 return mark_;
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 ///
|
Chris@16
|
88 /// Check if two periods are the same
|
Chris@16
|
89 ///
|
Chris@16
|
90 bool operator==(period_type const &other) const
|
Chris@16
|
91 {
|
Chris@16
|
92 return mark()==other.mark();
|
Chris@16
|
93 }
|
Chris@16
|
94 ///
|
Chris@16
|
95 /// Check if two periods are different
|
Chris@16
|
96 ///
|
Chris@16
|
97 bool operator!=(period_type const &other) const
|
Chris@16
|
98 {
|
Chris@16
|
99 return mark()!=other.mark();
|
Chris@16
|
100 }
|
Chris@16
|
101 private:
|
Chris@16
|
102 marks::period_mark mark_;
|
Chris@16
|
103 };
|
Chris@16
|
104
|
Chris@16
|
105 } // namespace period
|
Chris@16
|
106
|
Chris@16
|
107 ///
|
Chris@16
|
108 /// Structure that define POSIX time, seconds and milliseconds
|
Chris@16
|
109 /// since Jan 1, 1970, 00:00 not including leap seconds.
|
Chris@16
|
110 ///
|
Chris@16
|
111 struct posix_time {
|
Chris@16
|
112 int64_t seconds; ///< Seconds since epoch
|
Chris@16
|
113 uint32_t nanoseconds; ///< Nanoseconds resolution
|
Chris@16
|
114 };
|
Chris@16
|
115
|
Chris@16
|
116 ///
|
Chris@16
|
117 /// This class defines generic calendar class, it is used by date_time and calendar
|
Chris@16
|
118 /// objects internally. It is less useful for end users, but it is build for localization
|
Chris@16
|
119 /// backend implementation
|
Chris@16
|
120 ///
|
Chris@16
|
121
|
Chris@16
|
122 class abstract_calendar {
|
Chris@16
|
123 public:
|
Chris@16
|
124
|
Chris@16
|
125 ///
|
Chris@16
|
126 /// Type that defines how to fetch the value
|
Chris@16
|
127 ///
|
Chris@16
|
128 typedef enum {
|
Chris@16
|
129 absolute_minimum, ///< Absolute possible minimum for the value, for example for day is 1
|
Chris@16
|
130 actual_minimum, ///< Actual minimal value for this period.
|
Chris@16
|
131 greatest_minimum, ///< Maximal minimum value that can be for this period
|
Chris@16
|
132 current, ///< Current value of this period
|
Chris@16
|
133 least_maximum, ///< The last maximal value for this period, For example for Gregorian calendar
|
Chris@16
|
134 ///< day it is 28
|
Chris@16
|
135 actual_maximum, ///< Actual maximum, for it can be 28, 29, 30, 31 for day according to current month
|
Chris@16
|
136 absolute_maximum, ///< Maximal value, for Gregorian day it would be 31.
|
Chris@16
|
137 } value_type;
|
Chris@16
|
138
|
Chris@16
|
139 ///
|
Chris@16
|
140 /// A way to update the value
|
Chris@16
|
141 ///
|
Chris@16
|
142 typedef enum {
|
Chris@16
|
143 move, ///< Change the value up or down effecting others for example 1990-12-31 + 1 day = 1991-01-01
|
Chris@16
|
144 roll, ///< Change the value up or down not effecting others for example 1990-12-31 + 1 day = 1990-12-01
|
Chris@16
|
145 } update_type;
|
Chris@16
|
146
|
Chris@16
|
147 ///
|
Chris@16
|
148 /// Information about calendar
|
Chris@16
|
149 ///
|
Chris@16
|
150 typedef enum {
|
Chris@16
|
151 is_gregorian, ///< Check if the calendar is Gregorian
|
Chris@16
|
152 is_dst ///< Check if the current time is in daylight time savings
|
Chris@16
|
153 } calendar_option_type;
|
Chris@16
|
154
|
Chris@16
|
155 ///
|
Chris@16
|
156 /// Make a polymorphic copy of the calendar
|
Chris@16
|
157 ///
|
Chris@16
|
158 virtual abstract_calendar *clone() const = 0;
|
Chris@16
|
159
|
Chris@16
|
160 ///
|
Chris@16
|
161 /// Set specific \a value for period \a p, note not all values are settable.
|
Chris@16
|
162 ///
|
Chris@16
|
163 /// After call of set_value you may want to call normalize() function to make sure
|
Chris@16
|
164 /// vall periods are updated, if you set sereral fields that are part of single
|
Chris@16
|
165 /// date/time representation you should call set_value several times and then
|
Chris@16
|
166 /// call normalize().
|
Chris@16
|
167 ///
|
Chris@16
|
168 /// If normalize() is not called after set_value, the behavior is undefined
|
Chris@16
|
169 ///
|
Chris@16
|
170 virtual void set_value(period::marks::period_mark p,int value) = 0;
|
Chris@16
|
171
|
Chris@16
|
172 ///
|
Chris@16
|
173 /// Recalculate all periods after setting them, should be called after use of set_value() function.
|
Chris@16
|
174 ///
|
Chris@16
|
175 virtual void normalize() = 0;
|
Chris@16
|
176
|
Chris@16
|
177 ///
|
Chris@16
|
178 /// Get specific value for period \a p according to a value_type \a v
|
Chris@16
|
179 ///
|
Chris@16
|
180 virtual int get_value(period::marks::period_mark p,value_type v) const = 0;
|
Chris@16
|
181
|
Chris@16
|
182 ///
|
Chris@16
|
183 /// Set current time point
|
Chris@16
|
184 ///
|
Chris@16
|
185 virtual void set_time(posix_time const &p) = 0;
|
Chris@16
|
186 ///
|
Chris@16
|
187 /// Get current time point
|
Chris@16
|
188 ///
|
Chris@16
|
189 virtual posix_time get_time() const = 0;
|
Chris@16
|
190
|
Chris@16
|
191 ///
|
Chris@16
|
192 /// Set option for calendar, for future use
|
Chris@16
|
193 ///
|
Chris@16
|
194 virtual void set_option(calendar_option_type opt,int v) = 0;
|
Chris@16
|
195 ///
|
Chris@16
|
196 /// Get option for calendar, currently only check if it is Gregorian calendar
|
Chris@16
|
197 ///
|
Chris@16
|
198 virtual int get_option(calendar_option_type opt) const = 0;
|
Chris@16
|
199
|
Chris@16
|
200 ///
|
Chris@16
|
201 /// Adjust period's \a p value by \a difference items using a update_type \a u.
|
Chris@16
|
202 /// Note: not all values are adjustable
|
Chris@16
|
203 ///
|
Chris@16
|
204 virtual void adjust_value(period::marks::period_mark p,update_type u,int difference) = 0;
|
Chris@16
|
205
|
Chris@16
|
206 ///
|
Chris@16
|
207 /// Calculate the difference between this calendar and \a other in \a p units
|
Chris@16
|
208 ///
|
Chris@16
|
209 virtual int difference(abstract_calendar const *other,period::marks::period_mark p) const = 0;
|
Chris@16
|
210
|
Chris@16
|
211 ///
|
Chris@16
|
212 /// Set time zone, empty - use system
|
Chris@16
|
213 ///
|
Chris@16
|
214 virtual void set_timezone(std::string const &tz) = 0;
|
Chris@16
|
215 ///
|
Chris@16
|
216 /// Get current time zone, empty - system one
|
Chris@16
|
217 ///
|
Chris@16
|
218 virtual std::string get_timezone() const = 0;
|
Chris@16
|
219
|
Chris@16
|
220 ///
|
Chris@16
|
221 /// Check of two calendars have same rules
|
Chris@16
|
222 ///
|
Chris@16
|
223 virtual bool same(abstract_calendar const *other) const = 0;
|
Chris@16
|
224
|
Chris@16
|
225 virtual ~abstract_calendar()
|
Chris@16
|
226 {
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 };
|
Chris@16
|
230
|
Chris@16
|
231 ///
|
Chris@16
|
232 /// \brief the facet that generates calendar for specific locale
|
Chris@16
|
233 ///
|
Chris@16
|
234 class BOOST_LOCALE_DECL calendar_facet : public std::locale::facet {
|
Chris@16
|
235 public:
|
Chris@16
|
236 ///
|
Chris@16
|
237 /// Basic constructor
|
Chris@16
|
238 ///
|
Chris@16
|
239 calendar_facet(size_t refs = 0) : std::locale::facet(refs)
|
Chris@16
|
240 {
|
Chris@16
|
241 }
|
Chris@16
|
242 ///
|
Chris@16
|
243 /// Create a new calendar that points to current point of time.
|
Chris@16
|
244 ///
|
Chris@16
|
245 virtual abstract_calendar *create_calendar() const = 0;
|
Chris@16
|
246
|
Chris@16
|
247 ///
|
Chris@16
|
248 /// Locale id (needed to work with std::locale)
|
Chris@16
|
249 ///
|
Chris@16
|
250 static std::locale::id id;
|
Chris@16
|
251 };
|
Chris@16
|
252
|
Chris@16
|
253 } // locale
|
Chris@16
|
254 } // boost
|
Chris@16
|
255
|
Chris@16
|
256 #ifdef BOOST_MSVC
|
Chris@16
|
257 #pragma warning(pop)
|
Chris@16
|
258 #endif
|
Chris@16
|
259
|
Chris@16
|
260
|
Chris@16
|
261 #endif
|
Chris@16
|
262 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
Chris@16
|
263
|