3 * Original Author: Adapted from tzcode maintained by Arthur David Olson.
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 * - Implement localtime_r() with gmtime_r() and the conditional code moved
9 * from _mktm_r() - 05/09/14, Freddie Chopin <freddie_chopin@op.pl>
11 * Converts the calendar time pointed to by tim_p into a broken-down time
12 * expressed as local time. Returns a pointer to a structure containing the
19 localtime_r (const time_t *__restrict tim_p
,
20 struct tm
*__restrict res
)
23 int hours
, mins
, secs
;
25 __tzinfo_type
*const tz
= __gettzinfo ();
28 res
= gmtime_r (tim_p
, res
);
30 year
= res
->tm_year
+ YEAR_BASE
;
31 ip
= __month_lengths
[isleap(year
)];
37 if (year
== tz
->__tzyear
|| __tzcalc_limits (year
))
38 res
->tm_isdst
= (tz
->__tznorth
39 ? (*tim_p
>= tz
->__tzrule
[0].change
40 && *tim_p
< tz
->__tzrule
[1].change
)
41 : (*tim_p
>= tz
->__tzrule
[0].change
42 || *tim_p
< tz
->__tzrule
[1].change
));
49 offset
= (res
->tm_isdst
== 1
50 ? tz
->__tzrule
[1].offset
51 : tz
->__tzrule
[0].offset
);
53 hours
= (int) (offset
/ SECSPERHOUR
);
54 offset
= offset
% SECSPERHOUR
;
56 mins
= (int) (offset
/ SECSPERMIN
);
57 secs
= (int) (offset
% SECSPERMIN
);
61 res
->tm_hour
-= hours
;
63 if (res
->tm_sec
>= SECSPERMIN
)
66 res
->tm_sec
-= SECSPERMIN
;
68 else if (res
->tm_sec
< 0)
71 res
->tm_sec
+= SECSPERMIN
;
73 if (res
->tm_min
>= MINSPERHOUR
)
76 res
->tm_min
-= MINSPERHOUR
;
78 else if (res
->tm_min
< 0)
81 res
->tm_min
+= MINSPERHOUR
;
83 if (res
->tm_hour
>= HOURSPERDAY
)
90 res
->tm_hour
-= HOURSPERDAY
;
91 if (res
->tm_mday
> ip
[res
->tm_mon
])
93 res
->tm_mday
-= ip
[res
->tm_mon
];
95 if (res
->tm_mon
== 12)
103 else if (res
->tm_hour
< 0)
107 if (res
->tm_wday
< 0)
111 if (res
->tm_mday
== 0)
118 res
->tm_yday
= 364 + isleap(res
->tm_year
+ YEAR_BASE
);
120 res
->tm_mday
= ip
[res
->tm_mon
];