Chris@16: // Chris@16: // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: #ifndef BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED Chris@16: #define BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED Chris@16: Chris@16: #include Chris@16: #ifdef BOOST_MSVC Chris@16: # pragma warning(push) Chris@16: # pragma warning(disable : 4275 4251 4231 4660) Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace locale { Chris@16: /// Chris@16: /// \brief Namespace that contains various types for manipulation with dates Chris@16: /// Chris@16: namespace period { Chris@16: /// Chris@16: /// \brief This namespace holds a enum of various period types like era, year, month, etc.. Chris@16: /// Chris@16: namespace marks { Chris@16: /// \brief the type that defines a flag that holds a period identifier Chris@16: enum period_mark { Chris@16: invalid, ///< Special invalid value, should not be used directly Chris@16: era, ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] Chris@16: year, ///< Year, it is calendar specific, for example 2011 in Gregorian calendar. Chris@16: extended_year, ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. Chris@16: month, ///< The month of year, calendar specific, in Gregorian [0..11] Chris@16: day, ///< The day of month, calendar specific, in Gregorian [1..31] Chris@16: day_of_year, ///< The number of day in year, starting from 1, in Gregorian [1..366] Chris@16: day_of_week, ///< Day of week, Sunday=1, Monday=2,..., Saturday=7. Chris@16: ///< Note that updating this value respects local day of week, so for example, Chris@16: ///< If first day of week is Monday and the current day is Tuesday then setting Chris@16: ///< the value to Sunday (1) would forward the date by 5 days forward and not backward Chris@16: ///< by two days as it could be expected if the numbers were taken as is. Chris@16: day_of_week_in_month, ///< Original number of the day of the week in month. For example 1st Sunday, Chris@16: ///< 2nd Sunday, etc. in Gregorian [1..5] Chris@16: day_of_week_local, ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] Chris@16: hour, ///< 24 clock hour [0..23] Chris@16: hour_12, ///< 12 clock hour [0..11] Chris@16: am_pm, ///< am or pm marker [0..1] Chris@16: minute, ///< minute [0..59] Chris@16: second, ///< second [0..59] Chris@16: week_of_year, ///< The week number in the year Chris@16: week_of_month, ///< The week number within current month Chris@16: first_day_of_week, ///< First day of week, constant, for example Sunday in US = 1, Monday in France = 2 Chris@16: }; Chris@16: Chris@16: } // marks Chris@16: Chris@16: /// Chris@16: /// \brief This class holds a type that represents certain period of time like Chris@16: /// year, hour, second and so on. Chris@16: /// Chris@16: /// It can be created from either marks::period_mark type or by using shortcuts in period Chris@16: /// namespace - calling functions like period::year(), period::hour() and so on. Chris@16: /// Chris@16: /// Basically it represents the same object as enum marks::period_mark but allows to Chris@16: /// provide save operator overloading that would not collide with casing of enum to Chris@16: /// numeric values. Chris@16: /// Chris@16: class period_type { Chris@16: public: Chris@16: /// Chris@16: /// Create a period of specific type, default is invalid. Chris@16: /// Chris@16: period_type(marks::period_mark m = marks::invalid) : mark_(m) Chris@16: { Chris@16: } Chris@16: Chris@16: /// Chris@16: /// Get the value of marks::period_mark it was created with. Chris@16: /// Chris@16: marks::period_mark mark() const Chris@16: { Chris@16: return mark_; Chris@16: } Chris@16: Chris@16: /// Chris@16: /// Check if two periods are the same Chris@16: /// Chris@16: bool operator==(period_type const &other) const Chris@16: { Chris@16: return mark()==other.mark(); Chris@16: } Chris@16: /// Chris@16: /// Check if two periods are different Chris@16: /// Chris@16: bool operator!=(period_type const &other) const Chris@16: { Chris@16: return mark()!=other.mark(); Chris@16: } Chris@16: private: Chris@16: marks::period_mark mark_; Chris@16: }; Chris@16: Chris@16: } // namespace period Chris@16: Chris@16: /// Chris@16: /// Structure that define POSIX time, seconds and milliseconds Chris@16: /// since Jan 1, 1970, 00:00 not including leap seconds. Chris@16: /// Chris@16: struct posix_time { Chris@16: int64_t seconds; ///< Seconds since epoch Chris@16: uint32_t nanoseconds; ///< Nanoseconds resolution Chris@16: }; Chris@16: Chris@16: /// Chris@16: /// This class defines generic calendar class, it is used by date_time and calendar Chris@16: /// objects internally. It is less useful for end users, but it is build for localization Chris@16: /// backend implementation Chris@16: /// Chris@16: Chris@16: class abstract_calendar { Chris@16: public: Chris@16: Chris@16: /// Chris@16: /// Type that defines how to fetch the value Chris@16: /// Chris@16: typedef enum { Chris@16: absolute_minimum, ///< Absolute possible minimum for the value, for example for day is 1 Chris@16: actual_minimum, ///< Actual minimal value for this period. Chris@16: greatest_minimum, ///< Maximal minimum value that can be for this period Chris@16: current, ///< Current value of this period Chris@16: least_maximum, ///< The last maximal value for this period, For example for Gregorian calendar Chris@16: ///< day it is 28 Chris@16: actual_maximum, ///< Actual maximum, for it can be 28, 29, 30, 31 for day according to current month Chris@16: absolute_maximum, ///< Maximal value, for Gregorian day it would be 31. Chris@16: } value_type; Chris@16: Chris@16: /// Chris@16: /// A way to update the value Chris@16: /// Chris@16: typedef enum { Chris@16: move, ///< Change the value up or down effecting others for example 1990-12-31 + 1 day = 1991-01-01 Chris@16: roll, ///< Change the value up or down not effecting others for example 1990-12-31 + 1 day = 1990-12-01 Chris@16: } update_type; Chris@16: Chris@16: /// Chris@16: /// Information about calendar Chris@16: /// Chris@16: typedef enum { Chris@16: is_gregorian, ///< Check if the calendar is Gregorian Chris@16: is_dst ///< Check if the current time is in daylight time savings Chris@16: } calendar_option_type; Chris@16: Chris@16: /// Chris@16: /// Make a polymorphic copy of the calendar Chris@16: /// Chris@16: virtual abstract_calendar *clone() const = 0; Chris@16: Chris@16: /// Chris@16: /// Set specific \a value for period \a p, note not all values are settable. Chris@16: /// Chris@16: /// After call of set_value you may want to call normalize() function to make sure Chris@16: /// vall periods are updated, if you set sereral fields that are part of single Chris@16: /// date/time representation you should call set_value several times and then Chris@16: /// call normalize(). Chris@16: /// Chris@16: /// If normalize() is not called after set_value, the behavior is undefined Chris@16: /// Chris@16: virtual void set_value(period::marks::period_mark p,int value) = 0; Chris@16: Chris@16: /// Chris@16: /// Recalculate all periods after setting them, should be called after use of set_value() function. Chris@16: /// Chris@16: virtual void normalize() = 0; Chris@16: Chris@16: /// Chris@16: /// Get specific value for period \a p according to a value_type \a v Chris@16: /// Chris@16: virtual int get_value(period::marks::period_mark p,value_type v) const = 0; Chris@16: Chris@16: /// Chris@16: /// Set current time point Chris@16: /// Chris@16: virtual void set_time(posix_time const &p) = 0; Chris@16: /// Chris@16: /// Get current time point Chris@16: /// Chris@16: virtual posix_time get_time() const = 0; Chris@16: Chris@16: /// Chris@16: /// Set option for calendar, for future use Chris@16: /// Chris@16: virtual void set_option(calendar_option_type opt,int v) = 0; Chris@16: /// Chris@16: /// Get option for calendar, currently only check if it is Gregorian calendar Chris@16: /// Chris@16: virtual int get_option(calendar_option_type opt) const = 0; Chris@16: Chris@16: /// Chris@16: /// Adjust period's \a p value by \a difference items using a update_type \a u. Chris@16: /// Note: not all values are adjustable Chris@16: /// Chris@16: virtual void adjust_value(period::marks::period_mark p,update_type u,int difference) = 0; Chris@16: Chris@16: /// Chris@16: /// Calculate the difference between this calendar and \a other in \a p units Chris@16: /// Chris@16: virtual int difference(abstract_calendar const *other,period::marks::period_mark p) const = 0; Chris@16: Chris@16: /// Chris@16: /// Set time zone, empty - use system Chris@16: /// Chris@16: virtual void set_timezone(std::string const &tz) = 0; Chris@16: /// Chris@16: /// Get current time zone, empty - system one Chris@16: /// Chris@16: virtual std::string get_timezone() const = 0; Chris@16: Chris@16: /// Chris@16: /// Check of two calendars have same rules Chris@16: /// Chris@16: virtual bool same(abstract_calendar const *other) const = 0; Chris@16: Chris@16: virtual ~abstract_calendar() Chris@16: { Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: /// Chris@16: /// \brief the facet that generates calendar for specific locale Chris@16: /// Chris@16: class BOOST_LOCALE_DECL calendar_facet : public std::locale::facet { Chris@16: public: Chris@16: /// Chris@16: /// Basic constructor Chris@16: /// Chris@16: calendar_facet(size_t refs = 0) : std::locale::facet(refs) Chris@16: { Chris@16: } Chris@16: /// Chris@16: /// Create a new calendar that points to current point of time. Chris@16: /// Chris@16: virtual abstract_calendar *create_calendar() const = 0; Chris@16: Chris@16: /// Chris@16: /// Locale id (needed to work with std::locale) Chris@16: /// Chris@16: static std::locale::id id; Chris@16: }; Chris@16: Chris@16: } // locale Chris@16: } // boost Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: Chris@16: #endif Chris@16: // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 Chris@16: