29static int days_in_month_leap[13] = { 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
30static int days_in_month[13] = { 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
39 *b -= (
start - a_plus_1) / adj + 1;
43 *
a += adj * ((
start - a_plus_1) / adj);
48 *
a -= adj * (*
a / adj);
76 do_range_limit(1, 13, 12, base_m, base_y);
86 dec_month(&year, &month);
88 days = leapyear ? days_in_month_leap[month] : days_in_month[month];
98 days = leapyear ? days_in_month_leap[month] : days_in_month[month];
104 inc_month(&year, &month);
118 int *days_per_month_current_year;
126 do_range_limit(1, 13, 12, m, y);
129 days_per_month_current_year = leapyear ? days_in_month_leap : days_in_month;
131 while (*d <= 0 && *m > 0) {
132 previous_month = (*m) - 1;
133 if (previous_month < 1) {
134 previous_month += 12;
135 previous_year = (*y) - 1;
137 previous_year = (*y);
140 days_in_previous_month = leapyear ? days_in_month_leap[previous_month] : days_in_month[previous_month];
142 *d += days_in_previous_month;
146 while (*d > 0 && *m <= 12 && *d > days_per_month_current_year[*m]) {
147 *d -= days_per_month_current_year[*m];
159 if (
time->relative.weekday_behavior == 2)
162 if (current_dow == 0 &&
time->relative.weekday != 0) {
163 time->relative.weekday -= 7;
168 if (
time->relative.weekday == 0 && current_dow != 0) {
169 time->relative.weekday = 7;
172 time->d -= current_dow;
176 difference =
time->relative.weekday - current_dow;
177 if ((
time->relative.d < 0 && difference < 0) || (
time->relative.d >= 0 && difference <= -time->relative.weekday_behavior)) {
180 if (
time->relative.weekday >= 0) {
181 time->d += difference;
183 time->d -= (7 - (
abs(
time->relative.weekday) - current_dow));
185 time->relative.have_weekday_relative = 0;
190 do_range_limit(0, 1000000, 1000000, &rt->
us, &rt->
s);
191 do_range_limit(0, 60, 60, &rt->
s, &rt->
i);
192 do_range_limit(0, 60, 60, &rt->
i, &rt->
h);
193 do_range_limit(0, 24, 24, &rt->
h, &rt->
d);
194 do_range_limit(0, 12, 12, &rt->
m, &rt->
y);
196 do_range_limit_days_relative(&base->
y, &base->
m, &rt->
y, &rt->
m, &rt->
d, rt->
invert);
197 do_range_limit(0, 12, 12, &rt->
m, &rt->
y);
205 if (
time->d < -719498) {
211 y = (10000 * g + 14780) / 3652425;
212 ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
215 ddd = g - ((365*y) + (y/4) - (y/100) + (y/400));
217 mi = (100 * ddd + 52) / 3060;
218 mm = ((mi + 2) % 12) + 1;
219 y = y + (mi + 2) / 12;
220 dd = ddd - ((mi * 306 + 5) / 10) + 1;
232 do_range_limit(1, 13, 12, &
time->m, &
time->y);
236 magic_date_calc(
time);
239 do {}
while (do_range_limit_days(&
time->y, &
time->m, &
time->d));
240 do_range_limit(1, 13, 12, &
time->m, &
time->y);
245 if (
time->relative.have_weekday_relative) {
246 do_adjust_for_weekday(
time);
250 if (
time->have_relative) {
262 switch (
time->relative.first_last_day_of) {
293 }
else if (dow == 6) {
296 }
else if (dow == 6) {
300 }
else if (dow + rem > 5) {
312 }
else if (dow == 0) {
315 }
else if (dow == 0) {
317 }
else if (dow + rem < 1) {
327 if (
time->relative.have_special_relative) {
328 switch (
time->relative.special.type) {
330 do_adjust_special_weekday(
time);
335 memset(&(
time->relative.special), 0,
sizeof(
time->relative.special));
340 if (
time->relative.have_special_relative) {
341 switch (
time->relative.special.type) {
345 time->relative.m = 0;
350 time->relative.m = 0;
354 switch (
time->relative.first_last_day_of) {
388 int32_t current_offset = 0;
390 unsigned int current_is_dst = 0;
391 int32_t after_offset = 0;
395 int32_t actual_offset;
404 actual_offset = after_offset;
405 actual_transition_time = after_transition_time;
406 if (current_offset == after_offset && tz->
have_zone) {
408 if (current_offset >= 0 && tz->
dst && !current_is_dst) {
410 int32_t earlier_offset;
413 if ((earlier_offset != after_offset) && (tz->
sse - earlier_offset < after_transition_time)) {
415 actual_offset = earlier_offset;
416 actual_transition_time = earlier_transition_time;
418 }
else if (current_offset <= 0 && current_is_dst && !tz->dst) {
420 int32_t later_offset;
423 if ((later_offset != after_offset) && (tz->
sse - later_offset >= later_transition_time)) {
425 actual_offset = later_offset;
426 actual_transition_time = later_transition_time;
434 actual_transition_time != INT64_MIN &&
435 ((tz->
sse - actual_offset) >= (actual_transition_time + (current_offset - actual_offset))) &&
436 ((tz->
sse - actual_offset) < actual_transition_time)
439 if ((current_offset != actual_offset) && !in_transition) {
440 adjustment = -actual_offset;
442 adjustment = -current_offset;
445 tz->
sse += adjustment;
456 timelib_sll era, year_of_era, day_of_year, day_of_era;
461 day_of_year = (153 * (
time->m + (
time->m > 2 ? -3 : 9)) + 2)/5 +
time->d - 1;
462 day_of_era = year_of_era *
DAYS_PER_YEAR + year_of_era / 4 - year_of_era / 100 + day_of_year;
469 do_adjust_special_early(
time);
470 do_adjust_relative(
time);
471 do_adjust_special(
time);
484 do_adjust_timezone(
time, tzi);
486 time->sse_uptodate = 1;
487 time->have_relative =
time->relative.have_weekday_relative =
time->relative.have_special_relative =
time->relative.first_last_day_of = 0;
497 printf (
"%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
499 if (
time.have_relative) {
500 printf (
"%3dY %3dM %3dD / %3dH %3dM %3dS",
503 if (
time.have_weekday_relative) {
printf(string $format, mixed ... $values)
count(Countable|array $value, int $mode=COUNT_NORMAL)
timelib_sll timelib_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d)
memset(ptr, 0, type->size)
timelib_time * timelib_strtotime(const char *s, size_t len, timelib_error_container **errors, const timelib_tzdb *tzdb, timelib_tz_get_wrapper tz_get_wrapper)
int timelib_get_time_zone_offset_info(timelib_sll ts, timelib_tzinfo *tz, int32_t *offset, timelib_sll *transition_time, unsigned int *is_dst)
unsigned const char * end
unsigned int is_localtime
timelib_sll timelib_hms_to_seconds(timelib_sll h, timelib_sll m, timelib_sll s)
#define TIMELIB_ZONETYPE_ID
#define TIMELIB_ZONETYPE_OFFSET
struct _timelib_time timelib_time
void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz)
struct _timelib_rel_time timelib_rel_time
signed long long timelib_sll
struct _timelib_tzinfo timelib_tzinfo
#define TIMELIB_ZONETYPE_ABBR
#define TIMELIB_SPECIAL_WEEKDAY
#define HINNANT_EPOCH_SHIFT
#define TIMELIB_SPECIAL_FIRST_DAY_OF_MONTH
#define TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH
#define TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH
#define TIMELIB_BREAK_INTENTIONALLY_MISSING
#define TIMELIB_SPECIAL_LAST_DAY_OF_MONTH
#define timelib_is_leap(y)
void timelib_update_ts(timelib_time *time, timelib_tzinfo *tzi)
void timelib_do_normalize(timelib_time *time)
void timelib_do_rel_normalize(timelib_time *base, timelib_rel_time *rt)
timelib_sll timelib_epoch_days_from_time(timelib_time *time)