|
2
|
1 //======================================================================== |
|
|
2 // |
|
|
3 // timeutil.cxx |
|
|
4 // |
|
|
5 // ISO C date and time implementation support functions |
|
|
6 // |
|
|
7 //======================================================================== |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //####COPYRIGHTEND#### |
|
|
29 //======================================================================== |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
|
32 // Author(s): jlarmour |
|
|
33 // Contributors: jlarmour |
|
|
34 // Date: 1999-02-26 |
|
|
35 // Purpose: Provide support functions used by the ISO C date and time |
|
|
36 // implementation |
|
|
37 // Description: This file provides the functions: |
|
|
38 // cyg_libc_time_normalize_structtm() |
|
|
39 // cyg_libc_time_getzoneoffsets() |
|
|
40 // cyg_libc_time_setzoneoffsets() |
|
|
41 // cyg_libc_time_setdst() |
|
|
42 // and the globals: |
|
|
43 // cyg_libc_time_day_name |
|
|
44 // cyg_libc_time_day_name_len |
|
|
45 // cyg_libc_time_month_name |
|
|
46 // cyg_libc_time_month_name_len |
|
|
47 // cyg_libc_time_month_lengths |
|
|
48 // cyg_libc_time_current_dst_stat |
|
|
49 // cyg_libc_time_current_std_offset |
|
|
50 // cyg_libc_time_current_dst_offset |
|
|
51 // Usage: |
|
|
52 // |
|
|
53 //####DESCRIPTIONEND#### |
|
|
54 // |
|
|
55 //======================================================================== |
|
|
56 |
|
|
57 // CONFIGURATION |
|
|
58 |
|
|
59 #include <pkgconf/libc.h> // C library configuration |
|
|
60 |
|
|
61 // INCLUDES |
|
|
62 |
|
|
63 // define these functions as outline, not inline, functions in this file |
|
|
64 #define CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE extern "C" |
|
|
65 #define CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE extern "C" |
|
|
66 #define CYGPRI_LIBC_TIME_SETDST_INLINE extern "C" |
|
|
67 |
|
|
68 #include <cyg/infra/cyg_type.h> // Common type definitions and support |
|
|
69 #include <sys/timeutil.h> // Header for this file |
|
|
70 #include <time.h> // Main date and time definitions |
|
|
71 #include <stdlib.h> // for div() |
|
|
72 |
|
|
73 |
|
|
74 // GLOBALS |
|
|
75 |
|
|
76 // FIXME: PR19440 - const char & -fwritable-strings don't mix |
|
|
77 /*const*/ char cyg_libc_time_day_name[7][10] = { |
|
|
78 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", |
|
|
79 "Saturday" |
|
|
80 }; |
|
|
81 const cyg_uint8 cyg_libc_time_day_name_len[7] = { 6, 6, 7, 9, 8, 6, 8 }; |
|
|
82 |
|
|
83 // FIXME: PR19440 - const char & -fwritable-strings don't mix |
|
|
84 /*const*/ char cyg_libc_time_month_name[12][10] = { |
|
|
85 "January", "February", "March", "April", "May", "June", |
|
|
86 "July", "August", "September", "October", "November", "December" |
|
|
87 }; |
|
|
88 const cyg_uint8 cyg_libc_time_month_name_len[12] = { 7, 8, 5, 5, 3, 4, |
|
|
89 4, 6, 9, 7, 8, 8 }; |
|
|
90 |
|
|
91 const cyg_uint8 cyg_libc_time_month_lengths[2][12] = { |
|
|
92 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, |
|
|
93 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} |
|
|
94 }; |
|
|
95 |
|
|
96 Cyg_libc_time_dst cyg_libc_time_current_dst_stat = |
|
|
97 (Cyg_libc_time_dst)CYGNUM_LIBC_TIME_DST_DEFAULT_STATE; |
|
|
98 time_t cyg_libc_time_current_std_offset = |
|
|
99 (time_t)CYGNUM_LIBC_TIME_STD_DEFAULT_OFFSET; |
|
|
100 time_t cyg_libc_time_current_dst_offset = |
|
|
101 (time_t)CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET; |
|
|
102 |
|
|
103 |
|
|
104 // FUNCTIONS |
|
|
105 |
|
|
106 //////////////////////////////////////// |
|
|
107 // cyg_libc_time_normalize_structtm() // |
|
|
108 //////////////////////////////////////// |
|
|
109 // |
|
|
110 // cyg_libc_time_normalize_structtm() will adjust the fields of a struct tm |
|
|
111 // so that they are within the normal ranges expected. |
|
|
112 // tm_wday, tm_yday and tm_isdst are ignored |
|
|
113 |
|
|
114 externC void |
|
|
115 cyg_libc_time_normalize_structtm( struct tm *timeptr ) |
|
|
116 { |
|
|
117 div_t t; |
|
|
118 |
|
|
119 CYG_REPORT_FUNCNAME("cyg_libc_time_normalize_structtm"); |
|
|
120 CYG_REPORT_FUNCARG1("timeptr is at address %08x", timeptr); |
|
|
121 |
|
|
122 // normalize seconds to 0..59 |
|
|
123 if ((timeptr->tm_sec < 0) || (timeptr->tm_sec > 59)) { |
|
|
124 t = div(timeptr->tm_sec, 60); |
|
|
125 while (t.rem < 0) { |
|
|
126 t.rem += 60; |
|
|
127 --t.quot; |
|
|
128 } |
|
|
129 timeptr->tm_min += t.quot; |
|
|
130 timeptr->tm_sec = t.rem; |
|
|
131 } // if |
|
|
132 |
|
|
133 // normalize minutes to 0..59 |
|
|
134 if ((timeptr->tm_min < 0) || (timeptr->tm_min > 59)) { |
|
|
135 t = div(timeptr->tm_min, 60); |
|
|
136 while (t.rem < 0) { |
|
|
137 t.rem += 60; |
|
|
138 --t.quot; |
|
|
139 } |
|
|
140 timeptr->tm_hour += t.quot; |
|
|
141 timeptr->tm_min = t.rem; |
|
|
142 } // if |
|
|
143 |
|
|
144 // normalize hours to 0..23 |
|
|
145 if ((timeptr->tm_hour < 0) || (timeptr->tm_hour > 23)) { |
|
|
146 t = div(timeptr->tm_hour, 24); |
|
|
147 while (t.rem < 0) { |
|
|
148 t.rem += 24; |
|
|
149 --t.quot; |
|
|
150 } |
|
|
151 timeptr->tm_mday += t.quot; |
|
|
152 timeptr->tm_hour = t.rem; |
|
|
153 } // if |
|
|
154 |
|
|
155 // we wait before normalizing tm_mday as per ISO C 7.12.2.3 (although |
|
|
156 // actually it only makes sense if you think about it |
|
|
157 |
|
|
158 // normalize months to 0..11 |
|
|
159 if ((timeptr->tm_mon < 0) || (timeptr->tm_mon > 11)) { |
|
|
160 t = div(timeptr->tm_mon, 12); |
|
|
161 while (t.rem < 0) { |
|
|
162 t.rem += 12; |
|
|
163 --t.quot; |
|
|
164 } |
|
|
165 timeptr->tm_year += t.quot; |
|
|
166 timeptr->tm_mon = t.rem; |
|
|
167 } // if |
|
|
168 |
|
|
169 // now tm_mday which needs to go to 1..31 |
|
|
170 cyg_bool leap = cyg_libc_time_year_is_leap(timeptr->tm_year); |
|
|
171 |
|
|
172 while (timeptr->tm_mday < 1) { |
|
|
173 // move back a month |
|
|
174 |
|
|
175 if (--timeptr->tm_mon < 0) { |
|
|
176 --timeptr->tm_year; |
|
|
177 timeptr->tm_mon = 11; |
|
|
178 leap = cyg_libc_time_year_is_leap(timeptr->tm_year); |
|
|
179 } // if |
|
|
180 |
|
|
181 // we move backward the number of days in the _new_ current month |
|
|
182 timeptr->tm_mday += cyg_libc_time_month_lengths[leap][timeptr->tm_mon]; |
|
|
183 |
|
|
184 } // while |
|
|
185 |
|
|
186 while (timeptr->tm_mday > |
|
|
187 cyg_libc_time_month_lengths[leap][timeptr->tm_mon]) { |
|
|
188 |
|
|
189 // move forward a month |
|
|
190 |
|
|
191 // we move forward the number of days in the _old_ current month |
|
|
192 timeptr->tm_mday -= cyg_libc_time_month_lengths[leap][timeptr->tm_mon]; |
|
|
193 |
|
|
194 if (++timeptr->tm_mon > 11) { |
|
|
195 ++timeptr->tm_year; |
|
|
196 timeptr->tm_mon = 0; |
|
|
197 leap = cyg_libc_time_year_is_leap(timeptr->tm_year); |
|
|
198 } // if |
|
|
199 |
|
|
200 } // while |
|
|
201 |
|
|
202 CYG_REPORT_RETURN(); |
|
|
203 |
|
|
204 } // cyg_libc_time_normalize_structtm() |
|
|
205 |
|
|
206 |
|
|
207 // EOF timeutil.cxx |