date_time_facet.hpp 11 KB

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