CppCMS
|
00001 // 00002 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 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 } // period 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 } // locale 01136 } // boost 01137 01138 #ifdef BOOSTER_MSVC 01139 #pragma warning(pop) 01140 #endif 01141 01142 01143 #endif 01144 01145 01146 01147 01148 01149 01150 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4