File Coverage

/root/.cpan/build/Date-5.2.6-0/clib/src/panda/time/time.h
Criterion Covered Total %
statement 10 10 100.0
branch 3 6 50.0
condition n/a
subroutine n/a
pod n/a
total 13 16 81.2


line stmt bran cond sub pod time code
1             #pragma once
2             #include
3             #include
4             #include
5             #include
6             #include
7             #include
8             #include
9             #include
10              
11             namespace panda { namespace time {
12              
13             using ptime_t = int64_t;
14              
15             constexpr const size_t ZONE_ABBR_MAX = 7; // max length of local type abbrev name (MSK, EST, EDT, ...)
16             constexpr const size_t ZONE_ABBR_MIN = 3;
17              
18             static constexpr const ptime_t EPOCH_MAX = 67767976233446399l; // calculated for gmtime(s=59,m=59,h=23,mday=31,y=2**31-1) - 24 hours for possible tz offsets
19             static constexpr const ptime_t EPOCH_MIN = -67768100567884800l; // calculated for gmtime(s=00,m=00,h=00,mday=01,y=-2**31) + 24 hours for possible tz offsets
20             static constexpr const ptime_t EPOCH_NEGINF = std::numeric_limits::min();
21              
22             extern const int DAYS_IN_MONTH[2][12];
23             extern const int MON2YDAY[2][12];
24             extern const string_view MONTH_NAMES[12];
25             extern const string_view WDAY_NAMES[7];
26              
27             struct datetime {
28             ptime_t sec;
29             ptime_t min;
30             ptime_t hour;
31             ptime_t mday;
32             ptime_t mon;
33             int32_t yday;
34             int32_t wday;
35             int32_t year;
36             int32_t isdst;
37             int32_t gmtoff;
38             union {
39             char zone[ZONE_ABBR_MAX+1];
40             int64_t n_zone;
41             };
42             };
43              
44             struct Timezone;
45             using TimezoneSP = panda::iptr;
46              
47             TimezoneSP tzget (const string_view& zonename);
48             const TimezoneSP& tzlocal ();
49              
50             void tzset (const string_view& zonename);
51             void tzset (const TimezoneSP& = {});
52              
53             const string& tzdir ();
54             void tzdir (const string&);
55             const string& tzsysdir ();
56              
57             const string& tzembededdir();
58             void tzembededdir(const string&);
59              
60             void use_system_timezones ();
61             void use_embed_timezones();
62             std::vector available_timezones ();
63              
64             bool gmtime (ptime_t epoch, datetime* result);
65             datetime gmtime (ptime_t epoch);
66             ptime_t timegm (datetime* date);
67             ptime_t timegml (datetime* date);
68             ptime_t timegmll (const datetime* date);
69              
70             bool anytime (ptime_t epoch, datetime* result, const TimezoneSP& zone);
71             datetime anytime (ptime_t epoch, const TimezoneSP& zone);
72             ptime_t timeany (datetime* date, const TimezoneSP& zone);
73             ptime_t timeanyl (datetime* date, const TimezoneSP& zone);
74              
75             inline bool localtime (ptime_t epoch, datetime* result) { return anytime(epoch, result, tzlocal()); }
76             inline datetime localtime (ptime_t epoch) { return anytime(epoch, tzlocal()); }
77             inline ptime_t timelocal (datetime* date) { return timeany(date, tzlocal()); }
78             inline ptime_t timelocall (datetime* date) { return timeanyl(date, tzlocal()); }
79              
80             string strftime (string_view format, const datetime&);
81              
82 44 100         inline int is_leap_year (int32_t year) { return (year % 4) == 0 && ((year % 25) != 0 || (year % 16) == 0); }
    50          
    0          
83 44           inline int days_in_month (int32_t year, uint8_t month) { return DAYS_IN_MONTH[is_leap_year(year)][month]; }
84              
85             inline string_view month_name (int mon) { return MONTH_NAMES[mon]; }
86             inline string_view month_sname (int mon) { return MONTH_NAMES[mon].substr(0,3); }
87             inline string_view wday_name (int wday) { return WDAY_NAMES[wday]; }
88             inline string_view wday_sname (int wday) { return WDAY_NAMES[wday].substr(0,3); }
89              
90             // DAYS PASSED SINCE 1 Jan 0001 00:00:00 TILL 1 Jan 00:00:00
91 4           inline ptime_t christ_days (int32_t year) {
92 4           ptime_t yearpos = (ptime_t)year + 2147483999U;
93 4           ptime_t ret = yearpos*365;
94 4           yearpos >>= 2;
95 4           ret += yearpos;
96 4           yearpos /= 25;
97 4           ret -= yearpos - (yearpos >> 2) + (ptime_t)146097*5368710;
98 4           return ret;
99             }
100              
101             // DAYS PASSED SINCE 1 Jan 0001 00:00:00 TILL supplied date
102             inline ptime_t christ_days (int32_t year, uint8_t month, uint8_t mday) {
103             return christ_days(year) + MON2YDAY[is_leap_year(year)][month] + mday - 1;
104             }
105              
106             // returns week day number for supplied date (0=Sun, 6=Sat), only for dates later than 0000y
107             inline uint8_t wday (int32_t year, uint8_t month, uint8_t mday) {
108             return (1 + christ_days(year, month, mday)) % 7; // "1" because 1 Jan 0001 was monday :)
109             }
110              
111             struct Timezone : panda::AtomicRefcnt {
112             struct Transition {
113             ptime_t start; // time of transition
114             ptime_t local_start; // local time of transition (epoch+offset).
115             ptime_t local_end; // local time of transition's end (next transition epoch + MY offset).
116             ptime_t local_lower; // local_start or prev transition's local_end
117             ptime_t local_upper; // local_start or prev transition's local_end
118             int32_t offset; // offset from non-leap GMT
119             int32_t gmt_offset; // offset from leap GMT
120             int32_t delta; // offset minus previous transition's offset
121             int32_t isdst; // is DST in effect after this transition
122             int32_t leap_corr; // summary leap seconds correction at the moment
123             int32_t leap_delta; // delta leap seconds correction (0 if it's just a transition, != 0 if it's a leap correction)
124             ptime_t leap_end; // end of leap period (not including last second) = start + leap_delta
125             ptime_t leap_lend; // local_start + 2*leap_delta
126             union {
127             char abbrev[ZONE_ABBR_MAX+1]; // transition (zone) abbreviation
128             int64_t n_abbrev; // abbrev as int64_t
129             };
130             };
131              
132             struct Rule {
133             // rule for future (beyond transition list) dates and for abstract timezones
134             // http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
135             // --------------------------------------------------------------------------------------------
136             // 1 Jan OUTER ZONE OUTER END INNER ZONE INNER END OUTER ZONE 31 Dec
137             // --------------------------------------------------------------------------------------------
138             struct Zone {
139             enum class Switch { DATE, JDAY, DAY };
140             union {
141             char abbrev[ZONE_ABBR_MAX+1]; // zone abbreviation
142             int64_t n_abbrev; // abbrev as int64_t
143             };
144             int32_t offset; // offset from non-leap GMT
145             int32_t gmt_offset; // offset from leap GMT
146             int32_t isdst; // true if zone represents DST time
147             Switch type; // type of 'end' field
148             datetime end; // dynamic date when this zone ends (only if hasdst=1)
149             };
150              
151             uint32_t hasdst; // does this rule have DST switching
152             Zone outer; // always present
153             Zone inner; // only present if hasdst=1
154             int32_t max_offset; // max(outer.offset, inner.offset)
155             int32_t delta; // inner.offset - outer.offset
156             };
157              
158             struct Leap {
159             ptime_t time;
160             uint32_t correction;
161             };
162              
163             string name;
164             Transition* trans;
165             uint32_t trans_cnt;
166             Transition ltrans; // trans[trans_cnt-1]
167             Leap* leaps;
168             uint32_t leaps_cnt;
169             Rule future;
170             mutable bool is_local; // if timezone is set as local at the moment
171              
172             Timezone () {}
173              
174             void clear () {
175             delete[] this->trans;
176             if (this->leaps_cnt > 0) delete[] this->leaps;
177             }
178              
179             ~Timezone () { clear(); }
180             };
181              
182             }}
183