2 * COPYRIGHT: LGPL, See LGPL.txt in the top level directory
3 * PROJECT: ReactOS CRT library
4 * FILE: lib/sdk/crt/time/mktime.c
5 * PURPOSE: Implementation of mktime, _mkgmtime
6 * PROGRAMERS: Timo Kreuzer
11 #define MAX_32BIT_TIME 0xFFFFFFFFULL
13 static int g_monthdays
[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
16 mktime_worker(struct tm
* ptm
, int utc
)
20 int mons
, years
, leapyears
;
21 TIME_ZONE_INFORMATION tzi
;
24 /* Normalize year and month */
27 mons
= -ptm
->tm_mon
- 1;
28 ptm
->tm_year
-= 1 + mons
/ 12;
29 ptm
->tm_mon
= 11 - (mons
% 12);
31 else if (ptm
->tm_mon
> 11)
34 ptm
->tm_year
+= (mons
/ 12);
35 ptm
->tm_mon
= mons
% 12;
38 /* Is it inside margins */
39 if (ptm
->tm_year
< 70 || ptm
->tm_year
> 139) // FIXME: max year for 64 bits
44 years
= ptm
->tm_year
- 70;
46 /* Number of leapyears passed since 1970 */
47 leapyears
= (years
+ 1) / 4;
49 /* Calculate days up to 1st of Jan */
50 time
= years
* 365 + leapyears
;
52 /* Calculate days up to 1st of month */
53 time
+= g_monthdays
[ptm
->tm_mon
];
55 /* Check if we need to add a leap day */
56 if (((years
+ 2) % 4) == 0)
64 time
+= ptm
->tm_mday
- 1;
80 /* Finally get normalized tm struct */
81 ptm2
= _gmtime64(&time
);
88 /* Finally adjust by the difference to GMT in seconds */
89 ret
= GetTimeZoneInformation(&tzi
);
90 if (ret
!= TIME_ZONE_ID_INVALID
)
92 time
+= tzi
.Bias
* 60;
114 _mkgmtime(struct tm
*ptm
)
116 __time64_t time
= mktime_worker(ptm
, 1);
117 return (time_t)((time
> MAX_32BIT_TIME
) ? -1 : time
);
121 mktime(struct tm
*ptm
)
123 __time64_t time
= mktime_worker(ptm
, 0);
124 return (time_t)((time
> MAX_32BIT_TIME
) ? -1 : time
);
128 _mkgmtime32(struct tm
*ptm
)
130 __time64_t time
= mktime_worker(ptm
, 1);
131 return (__time32_t
)((time
> MAX_32BIT_TIME
) ? -1 : time
);
135 _mktime32(struct tm
*ptm
)
137 __time64_t time
= mktime_worker(ptm
, 0);
138 return (__time32_t
)((time
> MAX_32BIT_TIME
) ? -1 : time
);
142 _mkgmtime64(struct tm
*ptm
)
144 return mktime_worker(ptm
, 1);
148 _mktime64(struct tm
*ptm
)
150 return mktime_worker(ptm
, 0);