line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
namespace panda { namespace time { |
6
|
|
|
|
|
|
|
|
7
|
26
|
|
|
|
|
|
static const int64_t ZONE_N_GMT = *((int64_t*)"GMT\0\0\0\0"); |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
#define __PTIME_TRANS_BINFIND(VAR, FIELD) \ |
10
|
|
|
|
|
|
|
int index = -1; \ |
11
|
|
|
|
|
|
|
int low = 0; \ |
12
|
|
|
|
|
|
|
int high = zone->trans_cnt; \ |
13
|
|
|
|
|
|
|
while (high - low > 1) { \ |
14
|
|
|
|
|
|
|
int mid = (high+low)/2; \ |
15
|
|
|
|
|
|
|
if (zone->trans[mid].FIELD > VAR) high = mid; \ |
16
|
|
|
|
|
|
|
else if (zone->trans[mid].FIELD < VAR) low = mid; \ |
17
|
|
|
|
|
|
|
else { index = mid; break; } \ |
18
|
|
|
|
|
|
|
} \ |
19
|
|
|
|
|
|
|
if (index < 0) index = high - 1; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
#define _PTIME_LT_LEAPSEC_CORR(source) \ |
22
|
|
|
|
|
|
|
if (epoch < source.leap_end) result->sec = 60 + epoch - source.start; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
26899
|
|
|
|
|
|
static inline void _gmtime (ptime_t epoch, datetime* result) { |
26
|
26899
|
|
|
|
|
|
ptime_t sec_remainder = (epoch + OUTLIM_EPOCH_BY_86400) % 86400; |
27
|
26899
|
|
|
|
|
|
ptime_t delta_days = (epoch - sec_remainder)/86400; |
28
|
26899
|
|
|
|
|
|
result->wday = (OUTLIM_DAY_BY_7 + EPOCH_WDAY + delta_days) % 7; |
29
|
26899
|
|
|
|
|
|
result->hour = sec_remainder/3600; |
30
|
26899
|
|
|
|
|
|
sec_remainder %= 3600; |
31
|
26899
|
|
|
|
|
|
result->min = sec_remainder/60; |
32
|
26899
|
|
|
|
|
|
result->sec = sec_remainder % 60; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
int32_t year; |
35
|
|
|
|
|
|
|
int32_t remainder; |
36
|
26899
|
|
|
|
|
|
christ_year(EPOCH_CHRIST_DAYS + delta_days, year, remainder); |
37
|
|
|
|
|
|
|
|
38
|
26899
|
|
|
|
|
|
int leap = is_leap_year(year); |
39
|
26899
|
|
|
|
|
|
result->yday = remainder; |
40
|
26899
|
|
|
|
|
|
result->mon = YDAY2MON[leap][remainder]; |
41
|
26899
|
|
|
|
|
|
result->mday = YDAY2MDAY[leap][remainder]; |
42
|
26899
|
|
|
|
|
|
result->gmtoff = 0; |
43
|
26899
|
|
|
|
|
|
result->n_zone = ZONE_N_GMT; |
44
|
26899
|
|
|
|
|
|
result->isdst = 0; |
45
|
26899
|
|
|
|
|
|
result->year = year; |
46
|
26899
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
47534
|
100
|
|
|
|
|
static inline bool is_epoch_valid(ptime_t epoch) { return (epoch <= EPOCH_MAX) && (epoch >= EPOCH_MIN); } |
|
|
100
|
|
|
|
|
|
49
|
|
|
|
|
|
|
|
50
|
31341
|
|
|
|
|
|
static inline ptime_t _timegmll (const datetime* date) { |
51
|
31341
|
|
|
|
|
|
int leap = is_leap_year(date->year); |
52
|
31341
|
|
|
|
|
|
ptime_t delta_days = christ_days(date->year) + MON2YDAY[leap][date->mon] + date->mday - 1 - EPOCH_CHRIST_DAYS; |
53
|
31341
|
|
|
|
|
|
return delta_days * 86400 + date->hour * 3600 + date->min * 60 + date->sec; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
23827
|
|
|
|
|
|
static inline ptime_t _timegml (datetime* date) { |
57
|
23827
|
|
|
|
|
|
ptime_t mon_remainder = (date->mon + OUTLIM_MONTH_BY_12) % 12; |
58
|
23827
|
|
|
|
|
|
date->year += (date->mon - mon_remainder) / 12; |
59
|
23827
|
|
|
|
|
|
date->mon = mon_remainder; |
60
|
23827
|
|
|
|
|
|
return _timegmll(date); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
5
|
|
|
|
|
|
static inline ptime_t _timegm (datetime* date) { |
64
|
5
|
|
|
|
|
|
ptime_t result = _timegml(date); |
65
|
5
|
|
|
|
|
|
_gmtime(result, date); |
66
|
5
|
|
|
|
|
|
return result; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
4727
|
|
|
|
|
|
bool gmtime (ptime_t epoch, datetime* result) { |
70
|
4727
|
100
|
|
|
|
|
if (is_epoch_valid(epoch)){ |
71
|
4723
|
|
|
|
|
|
_gmtime(epoch, result); |
72
|
4723
|
|
|
|
|
|
return true; |
73
|
|
|
|
|
|
|
}; |
74
|
4
|
|
|
|
|
|
return false; |
75
|
|
|
|
|
|
|
} |
76
|
10
|
|
|
|
|
|
ptime_t timegm (datetime *date) { return _timegm(date); } |
77
|
9446
|
|
|
|
|
|
ptime_t timegml (datetime *date) { return _timegml(date); } |
78
|
|
|
|
|
|
|
|
79
|
7514
|
|
|
|
|
|
static inline ptime_t _calc_rule_epoch (int is_leap, const datetime* curdate, datetime border) { |
80
|
7514
|
|
|
|
|
|
border.mday = (border.wday + curdate->yday - MON2YDAY[is_leap][border.mon] - curdate->wday + 378) % 7 + 7*border.yday - 6; |
81
|
7514
|
50
|
|
|
|
|
if (border.mday > DAYS_IN_MONTH[is_leap][border.mon]) border.mday -= 7; |
82
|
7514
|
|
|
|
|
|
border.year = curdate->year; |
83
|
7514
|
|
|
|
|
|
return _timegmll(&border); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
19040
|
|
|
|
|
|
bool anytime (ptime_t epoch, datetime* result, const Timezone* zone) { |
87
|
19040
|
|
|
|
|
|
bool r = is_epoch_valid(epoch); |
88
|
19040
|
100
|
|
|
|
|
if (r) { |
89
|
19038
|
100
|
|
|
|
|
if (epoch < zone->ltrans.start) { |
90
|
118293
|
100
|
|
|
|
|
__PTIME_TRANS_BINFIND(epoch, start); |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
91
|
14545
|
|
|
|
|
|
_gmtime(epoch + zone->trans[index].offset, result); |
92
|
14545
|
|
|
|
|
|
result->gmtoff = zone->trans[index].gmt_offset; |
93
|
14545
|
|
|
|
|
|
result->n_zone = zone->trans[index].n_abbrev; |
94
|
14545
|
|
|
|
|
|
result->isdst = zone->trans[index].isdst; |
95
|
14545
|
100
|
|
|
|
|
_PTIME_LT_LEAPSEC_CORR(zone->trans[index]); |
96
|
|
|
|
|
|
|
} |
97
|
4493
|
100
|
|
|
|
|
else if (!zone->future.hasdst) { // future with no DST |
98
|
2520
|
|
|
|
|
|
_gmtime(epoch + zone->future.outer.offset, result); |
99
|
2520
|
|
|
|
|
|
result->n_zone = zone->future.outer.n_abbrev; |
100
|
2520
|
|
|
|
|
|
result->gmtoff = zone->future.outer.gmt_offset; |
101
|
2520
|
|
|
|
|
|
result->isdst = zone->future.outer.isdst; // some zones stay in dst in future (when no POSIX string and last trans is in dst) |
102
|
2520
|
50
|
|
|
|
|
_PTIME_LT_LEAPSEC_CORR(zone->ltrans); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
else { |
105
|
1973
|
|
|
|
|
|
_gmtime(epoch + zone->future.outer.offset, result); |
106
|
1973
|
|
|
|
|
|
int is_leap = is_leap_year(result->year); |
107
|
|
|
|
|
|
|
|
108
|
3512
|
100
|
|
|
|
|
if ((epoch >= _calc_rule_epoch(is_leap, result, zone->future.outer.end) - zone->future.outer.offset) && |
109
|
1539
|
|
|
|
|
|
(epoch < _calc_rule_epoch(is_leap, result, zone->future.inner.end) - zone->future.inner.offset)) { |
110
|
1104
|
|
|
|
|
|
_gmtime(epoch + zone->future.inner.offset, result); |
111
|
1104
|
|
|
|
|
|
result->isdst = zone->future.inner.isdst; |
112
|
1104
|
|
|
|
|
|
result->n_zone = zone->future.inner.n_abbrev; |
113
|
1104
|
|
|
|
|
|
result->gmtoff = zone->future.inner.gmt_offset; |
114
|
|
|
|
|
|
|
} else { |
115
|
869
|
|
|
|
|
|
result->isdst = zone->future.outer.isdst; |
116
|
869
|
|
|
|
|
|
result->n_zone = zone->future.outer.n_abbrev; |
117
|
869
|
|
|
|
|
|
result->gmtoff = zone->future.outer.gmt_offset; |
118
|
|
|
|
|
|
|
} |
119
|
19038
|
50
|
|
|
|
|
_PTIME_LT_LEAPSEC_CORR(zone->ltrans); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
}; |
122
|
19040
|
|
|
|
|
|
return r; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
30
|
|
|
|
|
|
ptime_t timeany (datetime* date, const Timezone* zone) { |
126
|
|
|
|
|
|
|
# define PTIME_ANY_NORMALIZE |
127
|
30
|
100
|
|
|
|
|
if (date->isdst > 0) { |
128
|
|
|
|
|
|
|
# undef PTIME_AMBIGUOUS_LATER |
129
|
|
|
|
|
|
|
# include |
130
|
|
|
|
|
|
|
} else { |
131
|
|
|
|
|
|
|
# define PTIME_AMBIGUOUS_LATER |
132
|
|
|
|
|
|
|
# include |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
# undef PTIME_ANY_NORMALIZE |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
19069
|
|
|
|
|
|
ptime_t timeanyl (datetime* date, const Timezone* zone) { |
138
|
19069
|
100
|
|
|
|
|
if (date->isdst > 0) { |
139
|
|
|
|
|
|
|
# undef PTIME_AMBIGUOUS_LATER |
140
|
|
|
|
|
|
|
# include |
141
|
|
|
|
|
|
|
} else { |
142
|
|
|
|
|
|
|
# define PTIME_AMBIGUOUS_LATER |
143
|
|
|
|
|
|
|
# include |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
11
|
|
|
|
|
|
size_t strftime (char* buf, size_t maxsize, const char* format, const datetime* timeptr) { |
148
|
|
|
|
|
|
|
tm systm; |
149
|
11
|
|
|
|
|
|
dt2tm(systm, *timeptr); |
150
|
11
|
|
|
|
|
|
return strftime(buf, maxsize, format, &systm); |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
|
void printftime (const char* format, const datetime* timeptr) { |
154
|
|
|
|
|
|
|
char buf[150]; |
155
|
0
|
0
|
|
|
|
|
strftime(buf, 150, format, timeptr); |
156
|
0
|
0
|
|
|
|
|
printf("%s", buf); |
157
|
0
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
104
|
50
|
|
|
|
|
}} |
|
|
50
|
|
|
|
|
|