3 * Original Author: Adapted from tzcode maintained by Arthur David Olson.
4 * Modifications: Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
6 * Converts the calendar time pointed to by tim_p into a broken-down time
7 * expressed as local time. Returns a pointer to a structure containing the
15 static _CONST
int mon_lengths
[2][MONSPERYEAR
] = {
16 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
17 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
20 static _CONST
int year_lengths
[2] = {
26 _DEFUN (_mktm_r
, (tim_p
, res
, is_gmtime
),
27 _CONST
time_t * tim_p _AND
38 /* base decision about std/dst time on current time */
41 days
= ((long)lcltime
) / SECSPERDAY
;
42 rem
= ((long)lcltime
) % SECSPERDAY
;
48 while (rem
>= SECSPERDAY
)
54 /* compute hour, min, and sec */
55 res
->tm_hour
= (int) (rem
/ SECSPERHOUR
);
57 res
->tm_min
= (int) (rem
/ SECSPERMIN
);
58 res
->tm_sec
= (int) (rem
% SECSPERMIN
);
60 /* compute day of week */
61 if ((res
->tm_wday
= ((EPOCH_WDAY
+ days
) % DAYSPERWEEK
)) < 0)
62 res
->tm_wday
+= DAYSPERWEEK
;
64 /* compute year & day of year */
71 if (days
< year_lengths
[yleap
])
74 days
-= year_lengths
[yleap
];
83 days
+= year_lengths
[yleap
];
87 res
->tm_year
= y
- YEAR_BASE
;
89 ip
= mon_lengths
[yleap
];
90 for (res
->tm_mon
= 0; days
>= ip
[res
->tm_mon
]; ++res
->tm_mon
)
91 days
-= ip
[res
->tm_mon
];
92 res
->tm_mday
= days
+ 1;
97 int hours
, mins
, secs
;
102 if (y
== __tzyear
|| __tzcalc_limits (y
))
103 res
->tm_isdst
= (__tznorth
104 ? (*tim_p
>= __tzrule
[0].change
&& *tim_p
< __tzrule
[1].change
)
105 : (*tim_p
>= __tzrule
[0].change
|| *tim_p
< __tzrule
[1].change
));
112 offset
= (res
->tm_isdst
== 1 ? __tzrule
[1].offset
: __tzrule
[0].offset
);
114 hours
= offset
/ SECSPERHOUR
;
115 offset
= offset
% SECSPERHOUR
;
117 mins
= offset
/ SECSPERMIN
;
118 secs
= offset
% SECSPERMIN
;
122 res
->tm_hour
-= hours
;
124 if (res
->tm_sec
>= SECSPERMIN
)
127 res
->tm_sec
-= SECSPERMIN
;
129 else if (res
->tm_sec
< 0)
132 res
->tm_sec
+= SECSPERMIN
;
134 if (res
->tm_min
>= MINSPERHOUR
)
137 res
->tm_min
-= MINSPERHOUR
;
139 else if (res
->tm_min
< 0)
142 res
->tm_min
+= MINSPERHOUR
;
144 if (res
->tm_hour
>= HOURSPERDAY
)
148 if (res
->tm_wday
> 6)
151 res
->tm_hour
-= HOURSPERDAY
;
152 if (res
->tm_mday
>= ip
[res
->tm_mon
])
154 res
->tm_mday
-= ip
[res
->tm_mon
] - 1;
156 if (res
->tm_mon
== 12)
164 else if (res
->tm_hour
< 0)
168 if (res
->tm_wday
< 0)
172 if (res
->tm_mday
== 0)
179 res
->tm_yday
= 365 + isleap(res
->tm_year
);
181 res
->tm_mday
= ip
[res
->tm_mon
];
193 _DEFUN (__tzcalc_limits
, (year
),
196 int days
, year_days
, years
;
199 if (year
< EPOCH_YEAR
)
204 years
= (year
- EPOCH_YEAR
);
206 year_days
= years
* 365 +
207 (years
- 1 + EPOCH_YEARS_SINCE_LEAP
) / 4 - (years
- 1 + EPOCH_YEARS_SINCE_CENTURY
) / 100 +
208 (years
- 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY
) / 400;
210 for (i
= 0; i
< 2; ++i
)
212 if (__tzrule
[i
].ch
== 'J')
213 days
= year_days
+ __tzrule
[i
].d
+ (isleap(year
) && __tzrule
[i
].d
>= 60);
214 else if (__tzrule
[i
].ch
== 'D')
215 days
= year_days
+ __tzrule
[i
].d
;
218 int yleap
= isleap(year
);
219 int m_day
, m_wday
, wday_diff
;
220 _CONST
int *ip
= mon_lengths
[yleap
];
224 for (j
= 1; j
< __tzrule
[i
].m
; ++j
)
227 m_wday
= (EPOCH_WDAY
+ days
) % DAYSPERWEEK
;
229 wday_diff
= __tzrule
[i
].d
- m_wday
;
231 wday_diff
+= DAYSPERWEEK
;
232 m_day
= (__tzrule
[i
].n
- 1) * DAYSPERWEEK
+ wday_diff
;
234 while (m_day
>= ip
[j
])
235 m_day
-= DAYSPERWEEK
;
240 /* store the change-over time in GMT form by adding offset */
241 __tzrule
[i
].change
= days
* SECSPERDAY
+ __tzrule
[i
].s
+ __tzrule
[i
].offset
;
244 __tznorth
= (__tzrule
[0].change
< __tzrule
[1].change
);