00001
00002
00003
00004
00005
00006
00007
00008 #ifndef BOOSTER_LOCALE_DATE_TIME_H_INCLUDED
00009 #define BOOSTER_LOCALE_DATE_TIME_H_INCLUDED
00010
00011 #include <booster/config.h>
00012 #ifdef BOOSTER_MSVC
00013 # pragma warning(push)
00014 # pragma warning(disable : 4275 4251 4231 4660)
00015 #endif
00016
00017 #include <booster/locale/hold_ptr.h>
00018 #include <booster/locale/date_time_facet.h>
00019 #include <booster/locale/formatting.h>
00020 #include <booster/locale/time_zone.h>
00021 #include <locale>
00022 #include <vector>
00023 #include <booster/backtrace.h>
00024
00025
00026 namespace booster {
00027 namespace locale {
00034
00035
00039 class date_time_error : public booster::runtime_error {
00040 public:
00044 date_time_error(std::string const &e) : booster::runtime_error(e) {}
00045 };
00046
00047
00056 struct date_time_period
00057 {
00058 period::period_type type;
00059 int value;
00060
00061
00062
00063 date_time_period operator+() const { return *this; }
00067 date_time_period operator-() const { return date_time_period(type,-value); }
00068
00072 date_time_period(period::period_type f=period::period_type(),int v=1) : type(f), value(v) {}
00073 };
00074
00075 namespace period {
00079 inline period_type invalid(){ return period_type(marks::invalid); }
00083 inline period_type era(){ return period_type(marks::era); }
00087 inline period_type year(){ return period_type(marks::year); }
00091 inline period_type extended_year(){ return period_type(marks::extended_year); }
00095 inline period_type month(){ return period_type(marks::month); }
00099 inline period_type day(){ return period_type(marks::day); }
00103 inline period_type day_of_year(){ return period_type(marks::day_of_year); }
00112 inline period_type day_of_week(){ return period_type(marks::day_of_week); }
00117 inline period_type day_of_week_in_month(){ return period_type(marks::day_of_week_in_month); }
00121 inline period_type day_of_week_local(){ return period_type(marks::day_of_week_local); }
00125 inline period_type hour(){ return period_type(marks::hour); }
00129 inline period_type hour_12(){ return period_type(marks::hour_12); }
00133 inline period_type am_pm(){ return period_type(marks::am_pm); }
00137 inline period_type minute(){ return period_type(marks::minute); }
00141 inline period_type second(){ return period_type(marks::second); }
00145 inline period_type week_of_year(){ return period_type(marks::week_of_year); }
00149 inline period_type week_of_month(){ return period_type(marks::week_of_month); }
00153 inline period_type first_day_of_week(){ return period_type(marks::first_day_of_week); }
00154
00158 inline date_time_period era(int v) { return date_time_period(era(),v); }
00162 inline date_time_period year(int v) { return date_time_period(year(),v); }
00166 inline date_time_period extended_year(int v) { return date_time_period(extended_year(),v); }
00170 inline date_time_period month(int v) { return date_time_period(month(),v); }
00174 inline date_time_period day(int v) { return date_time_period(day(),v); }
00178 inline date_time_period day_of_year(int v) { return date_time_period(day_of_year(),v); }
00187 inline date_time_period day_of_week(int v) { return date_time_period(day_of_week(),v); }
00192 inline date_time_period day_of_week_in_month(int v) { return date_time_period(day_of_week_in_month(),v); }
00196 inline date_time_period day_of_week_local(int v) { return date_time_period(day_of_week_local(),v); }
00200 inline date_time_period hour(int v) { return date_time_period(hour(),v); }
00204 inline date_time_period hour_12(int v) { return date_time_period(hour_12(),v); }
00208 inline date_time_period am_pm(int v) { return date_time_period(am_pm(),v); }
00212 inline date_time_period minute(int v) { return date_time_period(minute(),v); }
00216 inline date_time_period second(int v) { return date_time_period(second(),v); }
00220 inline date_time_period week_of_year(int v) { return date_time_period(week_of_year(),v); }
00224 inline date_time_period week_of_month(int v) { return date_time_period(week_of_month(),v); }
00228 inline date_time_period first_day_of_week(int v) { return date_time_period(first_day_of_week(),v); }
00229
00233 inline date_time_period january() { return date_time_period(month(),0); }
00237 inline date_time_period february() { return date_time_period(month(),1); }
00241 inline date_time_period march() { return date_time_period(month(),2); }
00245 inline date_time_period april() { return date_time_period(month(),3); }
00249 inline date_time_period may() { return date_time_period(month(),4); }
00253 inline date_time_period june() { return date_time_period(month(),5); }
00257 inline date_time_period july() { return date_time_period(month(),6); }
00261 inline date_time_period august() { return date_time_period(month(),7); }
00265 inline date_time_period september() { return date_time_period(month(),8); }
00269 inline date_time_period october() { return date_time_period(month(),9); }
00273 inline date_time_period november() { return date_time_period(month(),10); }
00277 inline date_time_period december() { return date_time_period(month(),11); }
00278
00282 inline date_time_period sunday() { return date_time_period(day_of_week(),1); }
00286 inline date_time_period monday() { return date_time_period(day_of_week(),2); }
00290 inline date_time_period tuesday() { return date_time_period(day_of_week(),3); }
00294 inline date_time_period wednesday() { return date_time_period(day_of_week(),4); }
00298 inline date_time_period thursday() { return date_time_period(day_of_week(),5); }
00302 inline date_time_period friday() { return date_time_period(day_of_week(),6); }
00306 inline date_time_period saturday() { return date_time_period(day_of_week(),7); }
00310 inline date_time_period am() { return date_time_period(am_pm(),0); }
00314 inline date_time_period pm() { return date_time_period(am_pm(),1); }
00315
00319 inline date_time_period operator+(period::period_type f)
00320 {
00321 return date_time_period(f);
00322 }
00326 inline date_time_period operator-(period::period_type f)
00327 {
00328 return date_time_period(f,-1);
00329 }
00330
00334 template<typename T>
00335 date_time_period operator*(period::period_type f,T v)
00336 {
00337 return date_time_period(f,v);
00338 }
00339
00343 template<typename T>
00344 date_time_period operator*(T v,period::period_type f)
00345 {
00346 return date_time_period(f,v);
00347 }
00351 template<typename T>
00352 date_time_period operator*(T v,date_time_period f)
00353 {
00354 return date_time_period(f.type,f.value*v);
00355 }
00356
00360 template<typename T>
00361 date_time_period operator*(date_time_period f,T v)
00362 {
00363 return date_time_period(f.type,f.value*v);
00364 }
00365
00366
00367 }
00368
00369
00376 class date_time_period_set {
00377 public:
00378
00382 date_time_period_set()
00383 {
00384 }
00388 date_time_period_set(period::period_type f)
00389 {
00390 basic_[0]=date_time_period(f);
00391 }
00395 date_time_period_set(date_time_period const &fl)
00396 {
00397 basic_[0]=fl;
00398 }
00402 void add(date_time_period f)
00403 {
00404 size_t n=size();
00405 if(n < 4)
00406 basic_[n]=f;
00407 else
00408 periods_.push_back(f);
00409 }
00413 size_t size() const
00414 {
00415 if(basic_[0].type == period::period_type())
00416 return 0;
00417 if(basic_[1].type == period::period_type())
00418 return 1;
00419 if(basic_[2].type == period::period_type())
00420 return 2;
00421 if(basic_[3].type == period::period_type())
00422 return 3;
00423 return 4+periods_.size();
00424 }
00428 date_time_period const &operator[](size_t n) const
00429 {
00430 if(n >= size())
00431 throw booster::out_of_range("Invalid index to date_time_period");
00432 if(n < 4)
00433 return basic_[n];
00434 else
00435 return periods_[n-4];
00436 }
00437 private:
00438 date_time_period basic_[4];
00439 std::vector<date_time_period> periods_;
00440 };
00441
00442
00446 inline date_time_period_set operator+(date_time_period_set const &a,date_time_period_set const &b)
00447 {
00448 date_time_period_set s(a);
00449 for(unsigned i=0;i<b.size();i++)
00450 s.add(b[i]);
00451 return s;
00452 }
00453
00457 inline date_time_period_set operator-(date_time_period_set const &a,date_time_period_set const &b)
00458 {
00459 date_time_period_set s(a);
00460 for(unsigned i=0;i<b.size();i++)
00461 s.add(-b[i]);
00462 return s;
00463 }
00464
00465
00473 class BOOSTER_API calendar {
00474 public:
00475
00482 calendar(std::ios_base &ios);
00488 calendar(std::locale const &l,std::string const &zone);
00494 calendar(std::locale const &l);
00500 calendar(std::string const &zone);
00506 calendar();
00507 ~calendar();
00508
00512 calendar(calendar const &other);
00516 calendar const &operator=(calendar const &other);
00517
00521 int minimum(period::period_type f) const;
00525 int greatest_minimum(period::period_type f) const;
00529 int maximum(period::period_type f) const;
00533 int least_maximum(period::period_type f) const;
00534
00537 int first_day_of_week() const;
00538
00542 std::locale get_locale() const;
00546 std::string get_time_zone() const;
00547
00551 bool is_gregorian() const;
00552
00556 bool operator==(calendar const &other) const;
00560 bool operator!=(calendar const &other) const;
00561
00562 private:
00563 friend class date_time;
00564 std::locale locale_;
00565 std::string tz_;
00566 hold_ptr<abstract_calendar> impl_;
00567 };
00568
00589
00590 class BOOSTER_API date_time {
00591 public:
00592
00598 date_time();
00602 date_time(date_time const &other);
00606 date_time(date_time const &other,date_time_period_set const &set);
00610 date_time const &operator=(date_time const &other);
00611 ~date_time();
00612
00618 date_time(double time);
00622 date_time(double time,calendar const &cal);
00626 date_time(calendar const &cal);
00627
00633 date_time(date_time_period_set const &set);
00637 date_time(date_time_period_set const &set,calendar const &cal);
00638
00639
00643 date_time const &operator=(date_time_period_set const &f);
00644
00648 void set(period::period_type f,int v);
00652 int get(period::period_type f) const;
00653
00657 int operator/(period::period_type f) const
00658 {
00659 return get(f);
00660 }
00661
00665 date_time operator+(period::period_type f) const
00666 {
00667 return *this+date_time_period(f);
00668 }
00669
00673 date_time operator-(period::period_type f) const
00674 {
00675 return *this-date_time_period(f);
00676 }
00677
00681 date_time const &operator+=(period::period_type f)
00682 {
00683 return *this+=date_time_period(f);
00684 }
00688 date_time const &operator-=(period::period_type f)
00689 {
00690 return *this-=date_time_period(f);
00691 }
00692
00696 date_time operator<<(period::period_type f) const
00697 {
00698 return *this<<date_time_period(f);
00699 }
00700
00704 date_time operator>>(period::period_type f) const
00705 {
00706 return *this>>date_time_period(f);
00707 }
00708
00712 date_time const &operator<<=(period::period_type f)
00713 {
00714 return *this<<=date_time_period(f);
00715 }
00719 date_time const &operator>>=(period::period_type f)
00720 {
00721 return *this>>=date_time_period(f);
00722 }
00723
00727 date_time operator+(date_time_period const &v) const;
00731 date_time operator-(date_time_period const &v) const;
00735 date_time const &operator+=(date_time_period const &v);
00739 date_time const &operator-=(date_time_period const &v);
00740
00744 date_time operator<<(date_time_period const &v) const;
00748 date_time operator>>(date_time_period const &v) const ;
00752 date_time const &operator<<=(date_time_period const &v);
00756 date_time const &operator>>=(date_time_period const &v);
00757
00761 date_time operator+(date_time_period_set const &v) const;
00765 date_time operator-(date_time_period_set const &v) const;
00769 date_time const &operator+=(date_time_period_set const &v);
00773 date_time const &operator-=(date_time_period_set const &v);
00774
00778 date_time operator<<(date_time_period_set const &v) const;
00782 date_time operator>>(date_time_period_set const &v) const ;
00786 date_time const &operator<<=(date_time_period_set const &v);
00790 date_time const &operator>>=(date_time_period_set const &v);
00791
00797 double time() const;
00804 void time(double v);
00805
00809 bool operator==(date_time const &other) const;
00813 bool operator!=(date_time const &other) const;
00817 bool operator<(date_time const &other) const;
00821 bool operator>(date_time const &other) const;
00825 bool operator<=(date_time const &other) const;
00829 bool operator>=(date_time const &other) const;
00830
00834 void swap(date_time &other);
00835
00839 int difference(date_time const &other,period::period_type f) const;
00840
00844 int minimum(period::period_type f) const;
00849 int maximum(period::period_type f) const;
00850
00854 bool is_in_daylight_saving_time() const;
00855
00856 private:
00857 hold_ptr<abstract_calendar> impl_;
00858 };
00859
00873 template<typename CharType>
00874 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,date_time const &t)
00875 {
00876 double time_point = t.time();
00877 uint64_t display_flags = ios_info::get(out).display_flags();
00878 if (
00879 display_flags == flags::date
00880 || display_flags == flags::time
00881 || display_flags == flags::datetime
00882 || display_flags == flags::strftime
00883 )
00884 {
00885 out << time_point;
00886 }
00887 else {
00888 ios_info::get(out).display_flags(flags::datetime);
00889 out << time_point;
00890 ios_info::get(out).display_flags(display_flags);
00891 }
00892 return out;
00893 }
00894
00900 template<typename CharType>
00901 std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,date_time &t)
00902 {
00903 double v;
00904 uint64_t display_flags = ios_info::get(in).display_flags();
00905 if (
00906 display_flags == flags::date
00907 || display_flags == flags::time
00908 || display_flags == flags::datetime
00909 || display_flags == flags::strftime
00910 )
00911 {
00912 in >> v;
00913 }
00914 else {
00915 ios_info::get(in).display_flags(flags::datetime);
00916 in >> v;
00917 ios_info::get(in).display_flags(display_flags);
00918 }
00919 if(!in.fail())
00920 t.time(v);
00921 return in;
00922 }
00923
00932 class date_time_duration {
00933 public:
00934
00939 date_time_duration(date_time const &first,date_time const &second) :
00940 s_(first),
00941 e_(second)
00942 {
00943 }
00944
00948 int get(period::period_type f) const
00949 {
00950 return start().difference(end(),f);
00951 }
00952
00956 int operator / (period::period_type f) const
00957 {
00958 return start().difference(end(),f);
00959 }
00960
00964 date_time const &start() const { return s_; }
00968 date_time const &end() const { return e_; }
00969 private:
00970 date_time const &s_;
00971 date_time const &e_;
00972 };
00973
00978 inline date_time_duration operator-(date_time const &later,date_time const &earlier)
00979 {
00980 return date_time_duration(earlier,later);
00981 }
00982
00983
00984 namespace period {
00988 inline int era(date_time const &dt) { return dt.get(era()); }
00992 inline int year(date_time const &dt) { return dt.get(year()); }
00996 inline int extended_year(date_time const &dt) { return dt.get(extended_year()); }
01000 inline int month(date_time const &dt) { return dt.get(month()); }
01004 inline int day(date_time const &dt) { return dt.get(day()); }
01008 inline int day_of_year(date_time const &dt) { return dt.get(day_of_year()); }
01017 inline int day_of_week(date_time const &dt) { return dt.get(day_of_week()); }
01022 inline int day_of_week_in_month(date_time const &dt) { return dt.get(day_of_week_in_month()); }
01026 inline int day_of_week_local(date_time const &dt) { return dt.get(day_of_week_local()); }
01030 inline int hour(date_time const &dt) { return dt.get(hour()); }
01034 inline int hour_12(date_time const &dt) { return dt.get(hour_12()); }
01038 inline int am_pm(date_time const &dt) { return dt.get(am_pm()); }
01042 inline int minute(date_time const &dt) { return dt.get(minute()); }
01046 inline int second(date_time const &dt) { return dt.get(second()); }
01050 inline int week_of_year(date_time const &dt) { return dt.get(week_of_year()); }
01054 inline int week_of_month(date_time const &dt) { return dt.get(week_of_month()); }
01058 inline int first_day_of_week(date_time const &dt) { return dt.get(first_day_of_week()); }
01059
01063 inline int era(date_time_duration const &dt) { return dt.get(era()); }
01067 inline int year(date_time_duration const &dt) { return dt.get(year()); }
01071 inline int extended_year(date_time_duration const &dt) { return dt.get(extended_year()); }
01075 inline int month(date_time_duration const &dt) { return dt.get(month()); }
01079 inline int day(date_time_duration const &dt) { return dt.get(day()); }
01083 inline int day_of_year(date_time_duration const &dt) { return dt.get(day_of_year()); }
01087 inline int day_of_week(date_time_duration const &dt) { return dt.get(day_of_week()); }
01091 inline int day_of_week_in_month(date_time_duration const &dt) { return dt.get(day_of_week_in_month()); }
01095 inline int day_of_week_local(date_time_duration const &dt) { return dt.get(day_of_week_local()); }
01099 inline int hour(date_time_duration const &dt) { return dt.get(hour()); }
01103 inline int hour_12(date_time_duration const &dt) { return dt.get(hour_12()); }
01107 inline int am_pm(date_time_duration const &dt) { return dt.get(am_pm()); }
01111 inline int minute(date_time_duration const &dt) { return dt.get(minute()); }
01115 inline int second(date_time_duration const &dt) { return dt.get(second()); }
01119 inline int week_of_year(date_time_duration const &dt) { return dt.get(week_of_year()); }
01123 inline int week_of_month(date_time_duration const &dt) { return dt.get(week_of_month()); }
01127 inline int first_day_of_week(date_time_duration const &dt) { return dt.get(first_day_of_week()); }
01128
01129
01130 }
01131
01133
01134
01135 }
01136 }
01137
01138 #ifdef BOOSTER_MSVC
01139 #pragma warning(pop)
01140 #endif
01141
01142
01143 #endif
01144
01145
01146
01147
01148
01149
01150