1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
27 * time conversion support
33 #define DAYS(p) (tm_data.days[(p)->tm_mon]+((p)->tm_mon==1&&LEAP(p)))
34 #define LEAP(p) (tmisleapyear((p)->tm_year))
37 * correct out of bounds fields in tm
39 * tm_isdst is not changed -- call tmxtm() to get that
41 * tm is the return value
45 tmfix(register Tm_t
* tm
)
53 * check for special case that adjusts tm_wday at the end
55 * nl_langinfo() => strftime() => tmfmt()
58 if (w
= !tm
->tm_sec
&& !tm
->tm_min
&& !tm
->tm_mday
&& !tm
->tm_year
&& !tm
->tm_yday
&& !tm
->tm_isdst
)
65 * adjust from shortest to longest units
68 if ((n
= tm
->tm_nsec
) < 0)
70 tm
->tm_sec
-= (TMX_RESOLUTION
- n
) / TMX_RESOLUTION
;
71 tm
->tm_nsec
= TMX_RESOLUTION
- (-n
) % TMX_RESOLUTION
;
73 else if (n
>= TMX_RESOLUTION
)
75 tm
->tm_sec
+= n
/ TMX_RESOLUTION
;
76 tm
->tm_nsec
%= TMX_RESOLUTION
;
78 if ((n
= tm
->tm_sec
) < 0)
80 tm
->tm_min
-= (60 - n
) / 60;
81 tm
->tm_sec
= 60 - (-n
) % 60;
83 else if (n
> (59 + TM_MAXLEAP
))
88 if ((n
= tm
->tm_min
) < 0)
90 tm
->tm_hour
-= (60 - n
) / 60;
91 n
= tm
->tm_min
= 60 - (-n
) % 60;
95 tm
->tm_hour
+= n
/ 60;
98 if ((n
= tm
->tm_hour
) < 0)
100 tm
->tm_mday
-= (23 - n
) / 24;
101 tm
->tm_hour
= 24 - (-n
) % 24;
105 tm
->tm_mday
+= n
/ 24;
108 if (tm
->tm_mon
>= 12)
110 tm
->tm_year
+= tm
->tm_mon
/ 12;
113 else if (tm
->tm_mon
< 0)
116 if ((tm
->tm_mon
+= 12) < 0)
118 tm
->tm_year
+= tm
->tm_mon
/ 12;
119 tm
->tm_mon
= (-tm
->tm_mon
) % 12;
122 while (tm
->tm_mday
< -365)
125 tm
->tm_mday
+= 365 + LEAP(tm
);
127 while (tm
->tm_mday
> 365)
129 tm
->tm_mday
-= 365 + LEAP(tm
);
132 while (tm
->tm_mday
< 1)
134 if (--tm
->tm_mon
< 0)
139 tm
->tm_mday
+= DAYS(tm
);
141 while (tm
->tm_mday
> (n
= DAYS(tm
)))
144 if (++tm
->tm_mon
> 11)
153 t
= tmtime(tm
, TM_LOCALZONE
);
155 if (w
= (w
- p
->tm_wday
))
160 if ((tm
->tm_mday
+= w
) > DAYS(tm
))
164 tm
->tm_yday
= tm_data
.sum
[tm
->tm_mon
] + (tm
->tm_mon
> 1 && LEAP(tm
)) + tm
->tm_mday
- 1;
165 n
= tm
->tm_year
+ 1900 - 1;
166 tm
->tm_wday
= (n
+ n
/ 4 - n
/ 100 + n
/ 400 + tm
->tm_yday
+ 1) % 7;
169 * tm_isdst is adjusted by tmtime()