1 | /* |
---|
2 | * tzcalc_limits.c |
---|
3 | * Original Author: Adapted from tzcode maintained by Arthur David Olson. |
---|
4 | * Modifications: |
---|
5 | * - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston |
---|
6 | * - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru> |
---|
7 | * - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru> |
---|
8 | * - Moved __tzcalc_limits() to separate file - 05/09/14, Freddie Chopin <freddie_chopin@op.pl> |
---|
9 | */ |
---|
10 | |
---|
11 | #include "local.h" |
---|
12 | |
---|
13 | int |
---|
14 | __tzcalc_limits (int year) |
---|
15 | { |
---|
16 | int days, year_days, years; |
---|
17 | int i, j; |
---|
18 | __tzinfo_type *const tz = __gettzinfo (); |
---|
19 | |
---|
20 | if (year < EPOCH_YEAR) |
---|
21 | return 0; |
---|
22 | |
---|
23 | tz->__tzyear = year; |
---|
24 | |
---|
25 | years = (year - EPOCH_YEAR); |
---|
26 | |
---|
27 | year_days = years * 365 + |
---|
28 | (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - |
---|
29 | (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + |
---|
30 | (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400; |
---|
31 | |
---|
32 | for (i = 0; i < 2; ++i) |
---|
33 | { |
---|
34 | if (tz->__tzrule[i].ch == 'J') |
---|
35 | { |
---|
36 | /* The Julian day n (1 <= n <= 365). */ |
---|
37 | days = year_days + tz->__tzrule[i].d + |
---|
38 | (isleap(year) && tz->__tzrule[i].d >= 60); |
---|
39 | /* Convert to yday */ |
---|
40 | --days; |
---|
41 | } |
---|
42 | else if (tz->__tzrule[i].ch == 'D') |
---|
43 | days = year_days + tz->__tzrule[i].d; |
---|
44 | else |
---|
45 | { |
---|
46 | const int yleap = isleap(year); |
---|
47 | int m_day, m_wday, wday_diff; |
---|
48 | const int *const ip = __month_lengths[yleap]; |
---|
49 | |
---|
50 | days = year_days; |
---|
51 | |
---|
52 | for (j = 1; j < tz->__tzrule[i].m; ++j) |
---|
53 | days += ip[j-1]; |
---|
54 | |
---|
55 | m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK; |
---|
56 | |
---|
57 | wday_diff = tz->__tzrule[i].d - m_wday; |
---|
58 | if (wday_diff < 0) |
---|
59 | wday_diff += DAYSPERWEEK; |
---|
60 | m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff; |
---|
61 | |
---|
62 | while (m_day >= ip[j-1]) |
---|
63 | m_day -= DAYSPERWEEK; |
---|
64 | |
---|
65 | days += m_day; |
---|
66 | } |
---|
67 | |
---|
68 | /* store the change-over time in GMT form by adding offset */ |
---|
69 | tz->__tzrule[i].change = days * SECSPERDAY + |
---|
70 | tz->__tzrule[i].s + tz->__tzrule[i].offset; |
---|
71 | } |
---|
72 | |
---|
73 | tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change); |
---|
74 | |
---|
75 | return 1; |
---|
76 | } |
---|