2 * mktime - convert local time into calendar time
6 /* Michael A. Temari <temari@ix.netcom.com> 03/01/96 */
7 /* - fixed bug is structure fixup code */
13 /* The code assumes that unsigned long can be converted to time_t.
14 * A time_t should not be wider than unsigned long, since this would mean
15 * that the check for overflow at the end could fail.
18 mktime(register struct tm
*timep
)
20 register long day
, year
;
23 register unsigned long seconds
;
27 timep
->tm_min
+= timep
->tm_sec
/ 60;
29 if (timep
->tm_sec
< 0) {
33 timep
->tm_hour
+= timep
->tm_min
/ 60;
34 timep
->tm_min
= timep
->tm_min
% 60;
35 if (timep
->tm_min
< 0) {
39 day
= timep
->tm_hour
/ 24;
40 timep
->tm_hour
= timep
->tm_hour
% 24;
41 if (timep
->tm_hour
< 0) {
45 timep
->tm_year
+= timep
->tm_mon
/ 12;
47 if (timep
->tm_mon
< 0) {
51 day
+= (timep
->tm_mday
- 1);
53 if(--timep
->tm_mon
< 0) {
57 day
+= _ytab
[LEAPYEAR(YEAR0
+ timep
->tm_year
)][timep
->tm_mon
];
59 while (day
>= _ytab
[LEAPYEAR(YEAR0
+ timep
->tm_year
)][timep
->tm_mon
]) {
60 day
-= _ytab
[LEAPYEAR(YEAR0
+ timep
->tm_year
)][timep
->tm_mon
];
61 if (++(timep
->tm_mon
) == 12) {
66 timep
->tm_mday
= day
+ 1;
67 _tzset(); /* set timezone and dst info */
69 if (timep
->tm_year
< year
- YEAR0
) return (time_t)-1;
71 day
= 0; /* means days since day 0 now */
74 /* Assume that when day becomes negative, there will certainly
75 * be overflow on seconds.
76 * The check for overflow needs not to be done for leapyears
78 * The code only works when year (1970) is not a leapyear.
81 #error EPOCH_YR != 1970
83 tm_year
= timep
->tm_year
+ YEAR0
;
85 if (LONG_MAX
/ 365 < tm_year
- year
) overflow
++;
86 day
= (tm_year
- year
) * 365;
87 if (LONG_MAX
- day
< (tm_year
- year
) / 4 + 1) overflow
++;
88 day
+= (tm_year
- year
) / 4
89 + ((tm_year
% 4) && tm_year
% 4 < year
% 4);
90 day
-= (tm_year
- year
) / 100
91 + ((tm_year
% 100) && tm_year
% 100 < year
% 100);
92 day
+= (tm_year
- year
) / 400
93 + ((tm_year
% 400) && tm_year
% 400 < year
% 400);
96 while (month
< timep
->tm_mon
) {
97 yday
+= _ytab
[LEAPYEAR(tm_year
)][month
];
100 yday
+= (timep
->tm_mday
- 1);
101 if (day
+ yday
< 0) overflow
++;
104 timep
->tm_yday
= yday
;
105 timep
->tm_wday
= (day
+ 4) % 7; /* day 0 was thursday (4) */
107 seconds
= ((timep
->tm_hour
* 60L) + timep
->tm_min
) * 60L + timep
->tm_sec
;
109 if ((TIME_MAX
- seconds
) / SECS_DAY
< day
) overflow
++;
110 seconds
+= day
* SECS_DAY
;
112 /* Now adjust according to timezone and daylight saving time */
114 if (((_timezone
> 0) && (TIME_MAX
- _timezone
< seconds
))
115 || ((_timezone
< 0) && (seconds
< -_timezone
)))
117 seconds
+= _timezone
;
119 if (timep
->tm_isdst
< 0)
120 dst
= _dstget(timep
);
121 else if (timep
->tm_isdst
)
125 if (dst
> seconds
) overflow
++; /* dst is always non-negative */
128 if (overflow
) return (time_t)-1;
130 if ((time_t)seconds
!= seconds
) return (time_t)-1;
131 return (time_t)seconds
;