]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/src/util/gregorian.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / locale / src / util / gregorian.cpp
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 #define BOOST_LOCALE_SOURCE
9 #include <boost/config.hpp>
10 #ifdef BOOST_MSVC
11 # pragma warning(disable : 4996)
12 #endif
13 #include <locale>
14 #include <string>
15 #include <ios>
16 #include <boost/locale/date_time_facet.hpp>
17 #include <boost/locale/date_time.hpp>
18 #include <stdlib.h>
19 #include <ctime>
20 #include <memory>
21 #include <algorithm>
22 #include <limits>
23
24 #include "timezone.hpp"
25 #include "gregorian.hpp"
26
27 namespace boost {
28 namespace locale {
29 namespace util {
30 namespace {
31
32 int is_leap(int year)
33 {
34 if(year % 400 == 0)
35 return 1;
36 if(year % 100 == 0)
37 return 0;
38 if(year % 4 == 0)
39 return 1;
40 return 0;
41 }
42
43 int days_in_month(int year,int month)
44 {
45 static const int tbl[2][12] = {
46 { 31,28,31,30,31,30,31,31,30,31,30,31 },
47 { 31,29,31,30,31,30,31,31,30,31,30,31 }
48 };
49 return tbl[is_leap(year)][month - 1];
50 }
51
52 inline int days_from_0(int year)
53 {
54 year--;
55 return 365 * year + (year / 400) - (year/100) + (year / 4);
56 }
57
58 int days_from_1970(int year)
59 {
60 static const int days_from_0_to_1970 = days_from_0(1970);
61 return days_from_0(year) - days_from_0_to_1970;
62 }
63
64 int days_from_1jan(int year,int month,int day)
65 {
66 static const int days[2][12] = {
67 { 0,31,59,90,120,151,181,212,243,273,304,334 },
68 { 0,31,60,91,121,152,182,213,244,274,305,335 }
69 };
70 return days[is_leap(year)][month-1] + day - 1;
71 }
72
73 std::time_t internal_timegm(std::tm const *t)
74 {
75 int year = t->tm_year + 1900;
76 int month = t->tm_mon;
77 if(month > 11) {
78 year += month/12;
79 month %= 12;
80 }
81 else if(month < 0) {
82 int years_diff = (-month + 11)/12;
83 year -= years_diff;
84 month+=12 * years_diff;
85 }
86 month++;
87 int day = t->tm_mday;
88 int day_of_year = days_from_1jan(year,month,day);
89 int days_since_epoch = days_from_1970(year) + day_of_year;
90
91 std::time_t seconds_in_day = 3600 * 24;
92 std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
93
94 return result;
95 }
96
97 } // anon
98
99
100
101
102 namespace {
103
104 // Locale dependent data
105
106 bool comparator(char const *left,char const *right)
107 {
108 return strcmp(left,right) < 0;
109 }
110
111 //
112 // Ref: CLDR 1.9 common/supplemental/supplementalData.xml
113 //
114 // monday - default
115 // fri - MV
116 // sat - AE AF BH DJ DZ EG ER ET IQ IR JO KE KW LY MA OM QA SA SD SO SY TN YE
117 // sun - AR AS AZ BW CA CN FO GE GL GU HK IL IN JM JP KG KR LA MH MN MO MP MT NZ PH PK SG TH TT TW UM US UZ VI ZW
118 //
119
120 int first_day_of_week(char const *terr) {
121 static char const * const sat[] = {
122 "AE","AF","BH","DJ","DZ","EG","ER","ET","IQ","IR",
123 "JO","KE","KW","LY","MA","OM","QA","SA","SD","SO",
124 "SY","TN","YE"
125 };
126 static char const * const sunday[] = {
127 "AR","AS","AZ","BW","CA","CN","FO","GE","GL","GU",
128 "HK","IL","IN","JM","JP","KG","KR","LA","MH","MN",
129 "MO","MP","MT","NZ","PH","PK","SG","TH","TT","TW",
130 "UM","US","UZ","VI","ZW"
131 };
132 if(strcmp(terr,"MV") == 0)
133 return 5; // fri
134 if(std::binary_search<char const * const *>(sat,sat+sizeof(sat)/(sizeof(sat[0])),terr,comparator))
135 return 6; // sat
136 if(std::binary_search<char const * const *>(sunday,sunday+sizeof(sunday)/(sizeof(sunday[0])),terr,comparator))
137 return 0; // sun
138 // default
139 return 1; // mon
140 }
141 }
142
143 class gregorian_calendar : public abstract_calendar {
144 public:
145
146 gregorian_calendar(std::string const &terr)
147 {
148 first_day_of_week_ = first_day_of_week(terr.c_str());
149 time_ = std::time(0);
150 is_local_ = true;
151 tzoff_ = 0;
152 from_time(time_);
153 }
154
155 ///
156 /// Make a polymorphic copy of the calendar
157 ///
158 virtual gregorian_calendar *clone() const
159 {
160 return new gregorian_calendar(*this);
161 }
162
163 ///
164 /// Set specific \a value for period \a p, note not all values are settable.
165 ///
166 virtual void set_value(period::marks::period_mark p,int value)
167 {
168 using namespace period::marks;
169 switch(p) {
170 case era: ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1]
171 return;
172 case year: ///< Year, it is calendar specific
173 case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
174 tm_updated_.tm_year = value - 1900;
175 break;
176 case month:
177 tm_updated_.tm_mon = value;
178 break;
179 case day:
180 tm_updated_.tm_mday = value;
181 break;
182 case hour: ///< 24 clock hour [0..23]
183 tm_updated_.tm_hour = value;
184 break;
185 case hour_12: ///< 12 clock hour [0..11]
186 tm_updated_.tm_hour = tm_updated_.tm_hour / 12 * 12 + value;
187 break;
188 case am_pm: ///< am or pm marker, [0..1]
189 tm_updated_.tm_hour = 12 * value + tm_updated_.tm_hour % 12;
190 break;
191 case minute: ///< minute [0..59]
192 tm_updated_.tm_min = value;
193 break;
194 case second:
195 tm_updated_.tm_sec = value;
196 break;
197 case day_of_year:
198 normalize();
199 tm_updated_.tm_mday += (value - (tm_updated_.tm_yday + 1));
200 break;
201 case day_of_week: ///< Day of week, starting from Sunday, [1..7]
202 if(value < 1) // make sure it is positive
203 value += (-value / 7) * 7 + 7;
204 // convert to local DOW
205 value = (value - 1 - first_day_of_week_ + 14) % 7 + 1;
206 // fall throght
207 case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
208 normalize();
209 tm_updated_.tm_mday += (value - 1) - (tm_updated_.tm_wday - first_day_of_week_ + 7) % 7;
210 break;
211 case day_of_week_in_month: ///< Original number of the day of the week in month. (1st sunday, 2nd sunday etc)
212 case week_of_year: ///< The week number in the year, 4 is the minimal number of days to be in month
213 case week_of_month: ///< The week number withing current month
214 {
215 normalize();
216 int current_week = get_value(p,current);
217 int diff = 7 * (value - current_week);
218 tm_updated_.tm_mday += diff;
219 }
220 break;
221 case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
222 default:
223 return;
224 }
225 normalized_ = false;
226 }
227
228 void normalize()
229 {
230 if(!normalized_) {
231 std::tm val = tm_updated_;
232 val.tm_isdst = -1;
233 val.tm_wday = -1; // indecator of error
234 std::time_t point = -1;
235 if(is_local_) {
236 point = std::mktime(&val);
237 if(point == static_cast<std::time_t>(-1)){
238 #ifndef BOOST_WINDOWS
239 // windows does not handle negative time_t, under other plaforms
240 // it may be actually valid value in 1969-12-31 23:59:59
241 // so we check that a filed was updated - does not happen in case of error
242 if(val.tm_wday == -1)
243 #endif
244 {
245 throw date_time_error("boost::locale::gregorian_calendar: invalid time");
246 }
247 }
248 }
249 else {
250 point = internal_timegm(&val);
251 #ifdef BOOST_WINDOWS
252 // Windows uses TLS, thread safe
253 std::tm *revert_point = 0;
254 if(point < 0 || (revert_point = gmtime(&point)) == 0)
255 throw date_time_error("boost::locale::gregorian_calendar time is out of range");
256 val = *revert_point;
257 #else
258 if(!gmtime_r(&point,&val))
259 throw date_time_error("boost::locale::gregorian_calendar invalid time");
260 #endif
261
262 }
263
264 time_ = point - tzoff_;
265 tm_ = val;
266 tm_updated_ = val;
267 normalized_ = true;
268 }
269 }
270
271 int get_week_number(int day,int wday) const
272 {
273 ///
274 /// This is the number of days that are considered withing
275 /// period such that the week belongs there
276 ///
277 static const int days_in_full_week = 4;
278
279
280 // Alaways use local week start
281 int current_dow = (wday - first_day_of_week_ + 7) % 7;
282 // Calculate local week day of Jan 1st.
283 int first_week_day = (current_dow + 700 - day) % 7;
284 // adding something big devidable by 7
285
286 int start_of_period_in_weeks;
287 if(first_week_day < days_in_full_week) {
288 start_of_period_in_weeks = - first_week_day;
289 }
290 else {
291 start_of_period_in_weeks = 7 - first_week_day;
292 }
293 int week_number_in_days = day - start_of_period_in_weeks;
294 if(week_number_in_days < 0)
295 return -1;
296 return week_number_in_days / 7 + 1;
297 }
298
299 ///
300 /// Get specific value for period \a p according to a value_type \a v
301 ///
302 virtual int get_value(period::marks::period_mark p,value_type v) const
303 {
304 using namespace period::marks;
305 switch(p) {
306 case era:
307 return 1;
308 case year:
309 case extended_year:
310 switch(v) {
311 case absolute_minimum:
312 case greatest_minimum:
313 case actual_minimum:
314 #ifdef BOOST_WINDOWS
315 return 1970; // Unix epoch windows can't handle negative time_t
316 #else
317 if(sizeof(std::time_t) == 4)
318 return 1901; // minimal year with 32 bit time_t
319 else
320 return 1;
321 #endif
322 case absolute_maximum:
323 case least_maximum:
324 case actual_maximum:
325 if(sizeof(std::time_t) == 4)
326 return 2038; // Y2K38 - maximal with 32 bit time_t
327 else
328 return std::numeric_limits<int>::max();
329 case current:
330 return tm_.tm_year + 1900;
331 };
332 break;
333 case month:
334 switch(v) {
335 case absolute_minimum:
336 case greatest_minimum:
337 case actual_minimum:
338 return 0;
339 case absolute_maximum:
340 case least_maximum:
341 case actual_maximum:
342 return 11;
343 case current:
344 return tm_.tm_mon;
345 };
346 break;
347 case day:
348 switch(v) {
349 case absolute_minimum:
350 case greatest_minimum:
351 case actual_minimum:
352 return 1;
353 case absolute_maximum:
354 return 31;
355 case least_maximum:
356 return 28;
357 case actual_maximum:
358 return days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
359 case current:
360 return tm_.tm_mday;
361 };
362 break;
363 case day_of_year: ///< The number of day in year, starting from 1
364 switch(v) {
365 case absolute_minimum:
366 case greatest_minimum:
367 case actual_minimum:
368 return 1;
369 case absolute_maximum:
370 return 366;
371 case least_maximum:
372 return 365;
373 case actual_maximum:
374 return is_leap(tm_.tm_year + 1900) ? 366 : 365;
375 case current:
376 return tm_.tm_yday + 1;
377 }
378 break;
379 case day_of_week: ///< Day of week, starting from Sunday, [1..7]
380 switch(v) {
381 case absolute_minimum:
382 case greatest_minimum:
383 case actual_minimum:
384 return 1;
385 case absolute_maximum:
386 case least_maximum:
387 case actual_maximum:
388 return 7;
389 case current:
390 return tm_.tm_wday + 1;
391 }
392 break;
393 case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
394 switch(v) {
395 case absolute_minimum:
396 case greatest_minimum:
397 case actual_minimum:
398 return 1;
399 case absolute_maximum:
400 case least_maximum:
401 case actual_maximum:
402 return 7;
403 case current:
404 return (tm_.tm_wday - first_day_of_week_ + 7) % 7 + 1;
405 }
406 break;
407 case hour: ///< 24 clock hour [0..23]
408 switch(v) {
409 case absolute_minimum:
410 case greatest_minimum:
411 case actual_minimum:
412 return 0;
413 case absolute_maximum:
414 case least_maximum:
415 case actual_maximum:
416 return 23;
417 case current:
418 return tm_.tm_hour;
419 }
420 break;
421 case hour_12: ///< 12 clock hour [0..11]
422 switch(v) {
423 case absolute_minimum:
424 case greatest_minimum:
425 case actual_minimum:
426 return 0;
427 case absolute_maximum:
428 case least_maximum:
429 case actual_maximum:
430 return 11;
431 case current:
432 return tm_.tm_hour % 12;
433 }
434 break;
435 case am_pm: ///< am or pm marker, [0..1]
436 switch(v) {
437 case absolute_minimum:
438 case greatest_minimum:
439 case actual_minimum:
440 return 0;
441 case absolute_maximum:
442 case least_maximum:
443 case actual_maximum:
444 return 1;
445 case current:
446 return tm_.tm_hour >= 12 ? 1 : 0;
447 }
448 break;
449 case minute: ///< minute [0..59]
450 switch(v) {
451 case absolute_minimum:
452 case greatest_minimum:
453 case actual_minimum:
454 return 0;
455 case absolute_maximum:
456 case least_maximum:
457 case actual_maximum:
458 return 59;
459 case current:
460 return tm_.tm_min;
461 }
462 break;
463 case second: ///< second [0..59]
464 switch(v) {
465 case absolute_minimum:
466 case greatest_minimum:
467 case actual_minimum:
468 return 0;
469 case absolute_maximum:
470 case least_maximum:
471 case actual_maximum:
472 return 59;
473 case current:
474 return tm_.tm_sec;
475 }
476 break;
477 case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
478 return first_day_of_week_ + 1;
479
480 case week_of_year: ///< The week number in the year
481 switch(v) {
482 case absolute_minimum:
483 case greatest_minimum:
484 case actual_minimum:
485 return 1;
486 case absolute_maximum:
487 return 53;
488 case least_maximum:
489 return 52;
490 case actual_maximum:
491 {
492 int year = tm_.tm_year + 1900;
493 int end_of_year_days = (is_leap(year) ? 366 : 365) - 1;
494 int dow_of_end_of_year = (end_of_year_days - tm_.tm_yday + tm_.tm_wday) % 7;
495 return get_week_number(end_of_year_days,dow_of_end_of_year);
496 }
497 case current:
498 {
499 int val = get_week_number(tm_.tm_yday,tm_.tm_wday);
500 if(val < 0)
501 return 53;
502 return val;
503 }
504 }
505 case week_of_month: ///< The week number withing current month
506 switch(v) {
507 case absolute_minimum:
508 case greatest_minimum:
509 case actual_minimum:
510 return 1;
511 case absolute_maximum:
512 return 5;
513 case least_maximum:
514 return 4;
515 case actual_maximum:
516 {
517 int end_of_month_days = days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1);
518 int dow_of_end_of_month = (end_of_month_days - tm_.tm_mday + tm_.tm_wday) % 7;
519 return get_week_number(end_of_month_days,dow_of_end_of_month);
520 }
521 case current:
522 {
523 int val = get_week_number(tm_.tm_mday,tm_.tm_wday);
524 if(val < 0)
525 return 5;
526 return val;
527 }
528 }
529
530 case day_of_week_in_month: ///< Original number of the day of the week in month.
531 switch(v) {
532 case absolute_minimum:
533 case greatest_minimum:
534 case actual_minimum:
535 return 1;
536 case absolute_maximum:
537 return 5;
538 case least_maximum:
539 return 4;
540 case actual_maximum:
541 if(tm_.tm_mon == 1 && !is_leap(tm_.tm_year + 1900)) {
542 // only in february in non leap year is 28 days, the rest
543 // conver more then 4 weeks
544 return 4;
545 }
546 return 5;
547 case current:
548 return (tm_.tm_mday - 1) / 7 + 1;
549 default:
550 ;
551 }
552 default:
553 ;
554 }
555 return 0;
556
557 }
558
559 ///
560 /// Set current time point
561 ///
562 virtual void set_time(posix_time const &p)
563 {
564 from_time(static_cast<std::time_t>(p.seconds));
565 }
566 virtual posix_time get_time() const
567 {
568 posix_time pt = { time_, 0};
569 return pt;
570 }
571
572 ///
573 /// Set option for calendar, for future use
574 ///
575 virtual void set_option(calendar_option_type opt,int /*v*/)
576 {
577 switch(opt) {
578 case is_gregorian:
579 throw date_time_error("is_gregorian is not settable options for calendar");
580 case is_dst:
581 throw date_time_error("is_dst is not settable options for calendar");
582 default:
583 ;
584 }
585 }
586 ///
587 /// Get option for calendar, currently only check if it is Gregorian calendar
588 ///
589 virtual int get_option(calendar_option_type opt) const
590 {
591 switch(opt) {
592 case is_gregorian:
593 return 1;
594 case is_dst:
595 return tm_.tm_isdst == 1;
596 default:
597 return 0;
598 };
599 }
600
601 ///
602 /// Adjust period's \a p value by \a difference items using a update_type \a u.
603 /// Note: not all values are adjustable
604 ///
605 virtual void adjust_value(period::marks::period_mark p,update_type u,int difference)
606 {
607 switch(u) {
608 case move:
609 {
610 using namespace period::marks;
611 switch(p) {
612 case year: ///< Year, it is calendar specific
613 case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1.
614 tm_updated_.tm_year +=difference;
615 break;
616 case month:
617 tm_updated_.tm_mon +=difference;
618 break;
619 case day:
620 case day_of_year:
621 case day_of_week: ///< Day of week, starting from Sunday, [1..7]
622 case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7]
623 tm_updated_.tm_mday +=difference;
624 break;
625 case hour: ///< 24 clock hour [0..23]
626 case hour_12: ///< 12 clock hour [0..11]
627 tm_updated_.tm_hour += difference;
628 break;
629 case am_pm: ///< am or pm marker, [0..1]
630 tm_updated_.tm_hour += 12 * difference;
631 break;
632 case minute: ///< minute [0..59]
633 tm_updated_.tm_min += difference;
634 break;
635 case second:
636 tm_updated_.tm_sec += difference;
637 break;
638 case week_of_year: ///< The week number in the year
639 case week_of_month: ///< The week number withing current month
640 case day_of_week_in_month: ///< Original number of the day of the week in month.
641 tm_updated_.tm_mday +=difference * 7;
642 break;
643 default:
644 ; // Not all values are adjustable
645 }
646 normalized_ = false;
647 normalize();
648 }
649 break;
650 case roll:
651 { // roll
652 int cur_min = get_value(p,actual_minimum);
653 int cur_max = get_value(p,actual_maximum);
654 int max_diff = cur_max - cur_min + 1;
655 if(max_diff > 0) {
656 int value = get_value(p,current);
657 int addon = 0;
658 if(difference < 0)
659 addon = ((-difference/max_diff) + 1) * max_diff;
660 value = (value - cur_min + difference + addon) % max_diff + cur_min;
661 set_value(p,value);
662 normalize();
663 }
664 }
665 default:
666 ;
667 }
668 }
669
670 int get_diff(period::marks::period_mark p,int diff,gregorian_calendar const *other) const
671 {
672 if(diff == 0)
673 return 0;
674 std::auto_ptr<gregorian_calendar> self(clone());
675 self->adjust_value(p,move,diff);
676 if(diff > 0){
677 if(self->time_ > other->time_)
678 return diff - 1;
679 else
680 return diff;
681 }
682 else {
683 if(self->time_ < other->time_)
684 return diff + 1;
685 else
686 return diff;
687 }
688 }
689
690 ///
691 /// Calculate the difference between this calendar and \a other in \a p units
692 ///
693 virtual int difference(abstract_calendar const *other_cal,period::marks::period_mark p) const
694 {
695 std::auto_ptr<gregorian_calendar> keeper;
696 gregorian_calendar const *other = dynamic_cast<gregorian_calendar const *>(other_cal);
697 if(!other) {
698 keeper.reset(clone());
699 keeper->set_time(other_cal->get_time());
700 other = keeper.get();
701 }
702
703 int factor = 1; // for weeks vs days handling
704
705 using namespace period::marks;
706 switch(p) {
707 case era:
708 return 0;
709 case year:
710 case extended_year:
711 {
712 int diff = other->tm_.tm_year - tm_.tm_year;
713 return get_diff(period::marks::year,diff,other);
714 }
715 case month:
716 {
717 int diff = 12 * (other->tm_.tm_year - tm_.tm_year)
718 + other->tm_.tm_mon - tm_.tm_mon;
719 return get_diff(period::marks::month,diff,other);
720 }
721 case day_of_week_in_month:
722 case week_of_month:
723 case week_of_year:
724 factor = 7;
725 // fall
726 case day:
727 case day_of_year:
728 case day_of_week:
729 case day_of_week_local:
730 {
731 int diff = other->tm_.tm_yday - tm_.tm_yday;
732 if(other->tm_.tm_year != tm_.tm_year) {
733 diff += days_from_0(other->tm_.tm_year + 1900) -
734 days_from_0(tm_.tm_year + 1900);
735 }
736 return get_diff(period::marks::day,diff,other) / factor;
737 }
738 case am_pm:
739 return static_cast<int>( (other->time_ - time_) / (3600*12) );
740 case hour:
741 case hour_12:
742 return static_cast<int>( (other->time_ - time_) / 3600 );
743 case minute:
744 return static_cast<int>( (other->time_ - time_) / 60 );
745 case second:
746 return static_cast<int>( other->time_ - time_ );
747 default:
748 return 0;
749 };
750 }
751
752 ///
753 /// Set time zone, empty - use system
754 ///
755 virtual void set_timezone(std::string const &tz)
756 {
757 if(tz.empty()) {
758 is_local_ = true;
759 tzoff_ = 0;
760 }
761 else {
762 is_local_ = false;
763 tzoff_ = parse_tz(tz);
764 }
765 from_time(time_);
766 time_zone_name_ = tz;
767 }
768 virtual std::string get_timezone() const
769 {
770 return time_zone_name_;
771 }
772
773 virtual bool same(abstract_calendar const *other) const
774 {
775 gregorian_calendar const *gcal = dynamic_cast<gregorian_calendar const *>(other);
776 if(!gcal)
777 return false;
778 return
779 gcal->tzoff_ == tzoff_
780 && gcal->is_local_ == is_local_
781 && gcal->first_day_of_week_ == first_day_of_week_;
782 }
783
784 virtual ~gregorian_calendar()
785 {
786 }
787
788 private:
789
790 void from_time(std::time_t point)
791 {
792 std::time_t real_point = point + tzoff_;
793 std::tm *t = 0;
794 #ifdef BOOST_WINDOWS
795 // Windows uses TLS, thread safe
796 t = is_local_ ? localtime(&real_point) : gmtime(&real_point);
797 #else
798 std::tm tmp_tm;
799 t = is_local_ ? localtime_r(&real_point,&tmp_tm) : gmtime_r(&real_point,&tmp_tm);
800 #endif
801 if(!t) {
802 throw date_time_error("boost::locale::gregorian_calendar: invalid time point");
803 }
804 tm_ = *t;
805 tm_updated_ = *t;
806 normalized_ = true;
807 time_ = point;
808 }
809 int first_day_of_week_;
810 std::time_t time_;
811 std::tm tm_;
812 std::tm tm_updated_;
813 bool normalized_;
814 bool is_local_;
815 int tzoff_;
816 std::string time_zone_name_;
817
818 };
819
820 abstract_calendar *create_gregorian_calendar(std::string const &terr)
821 {
822 return new gregorian_calendar(terr);
823 }
824
825 class gregorian_facet : public calendar_facet {
826 public:
827 gregorian_facet(std::string const &terr,size_t refs = 0) :
828 calendar_facet(refs),
829 terr_(terr)
830 {
831 }
832 virtual abstract_calendar *create_calendar() const
833 {
834 return create_gregorian_calendar(terr_);
835 }
836 private:
837 std::string terr_;
838 };
839
840 std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr)
841 {
842 return std::locale(in,new gregorian_facet(terr));
843 }
844
845
846 } // util
847 } // locale
848 } //boost
849
850
851 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4