Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / time / lcltime_r.c
blob9b9126bcccacd4012ca1d7b45d53b0ab20a7d416
1 /*
2 * localtime_r.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 * - 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
13 * broken-down time.
16 #include "local.h"
18 struct tm *
19 localtime_r (const time_t *__restrict tim_p,
20 struct tm *__restrict res)
22 long offset;
23 int hours, mins, secs;
24 int year;
25 __tzinfo_type *const tz = __gettzinfo ();
26 const int *ip;
28 res = gmtime_r (tim_p, res);
30 year = res->tm_year + YEAR_BASE;
31 ip = __month_lengths[isleap(year)];
33 TZ_LOCK;
34 _tzset_unlocked ();
35 if (_daylight)
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));
43 else
44 res->tm_isdst = -1;
46 else
47 res->tm_isdst = 0;
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);
59 res->tm_sec -= secs;
60 res->tm_min -= mins;
61 res->tm_hour -= hours;
63 if (res->tm_sec >= SECSPERMIN)
65 res->tm_min += 1;
66 res->tm_sec -= SECSPERMIN;
68 else if (res->tm_sec < 0)
70 res->tm_min -= 1;
71 res->tm_sec += SECSPERMIN;
73 if (res->tm_min >= MINSPERHOUR)
75 res->tm_hour += 1;
76 res->tm_min -= MINSPERHOUR;
78 else if (res->tm_min < 0)
80 res->tm_hour -= 1;
81 res->tm_min += MINSPERHOUR;
83 if (res->tm_hour >= HOURSPERDAY)
85 ++res->tm_yday;
86 ++res->tm_wday;
87 if (res->tm_wday > 6)
88 res->tm_wday = 0;
89 ++res->tm_mday;
90 res->tm_hour -= HOURSPERDAY;
91 if (res->tm_mday > ip[res->tm_mon])
93 res->tm_mday -= ip[res->tm_mon];
94 res->tm_mon += 1;
95 if (res->tm_mon == 12)
97 res->tm_mon = 0;
98 res->tm_year += 1;
99 res->tm_yday = 0;
103 else if (res->tm_hour < 0)
105 res->tm_yday -= 1;
106 res->tm_wday -= 1;
107 if (res->tm_wday < 0)
108 res->tm_wday = 6;
109 res->tm_mday -= 1;
110 res->tm_hour += 24;
111 if (res->tm_mday == 0)
113 res->tm_mon -= 1;
114 if (res->tm_mon < 0)
116 res->tm_mon = 11;
117 res->tm_year -= 1;
118 res->tm_yday = 364 + isleap(res->tm_year + YEAR_BASE);
120 res->tm_mday = ip[res->tm_mon];
123 TZ_UNLOCK;
125 return (res);