1 /***
2 *loctim64.c - Convert __time64_t value to time structure
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 * Converts time stored as a __time64_t value to a structure of type
8 * struct tm expressed as local time.
9 *
10 *******************************************************************************/
11
12 #include <cruntime.h>
13 #include <limits.h>
14 #include <time.h>
15 #include <stddef.h>
16 #include <memory.h>
17 #include <ctime.h>
18 #include <internal.h>
19
20
21 /***
22 *struct tm *_localtime64_s(ptm, ptime) - convert __time64_t value to tm structure
23 *
24 *Purpose:
25 * Convert a value in 64-bit internal (__time64_t) format to a tm struct
26 * containing the corresponding local time.
27 *
28 * NOTES:
29 * (1) gmtime must be called before _isindst to ensure that the tb time
30 * structure is initialized.
31 * (2) gmtime, _gtime64, localtime and _localtime64() all use a single
32 * statically allocated buffer. Each call to one of these routines
33 * destroys the contents of the previous call.
34 * (3) It is assumed that __time64_t is a 64-bit integer representing
35 * the number of seconds since 00:00:00, 01-01-70 (UTC) (i.e., the
36 * Posix/Unix Epoch. Only non-negative values are supported.
37 * (4) It is assumed that the maximum adjustment for local time is
38 * less than three days (include Daylight Savings Time adjustment).
39 * This only a concern in Posix where the specification of the TZ
40 * environment restricts the combined offset for time zone and
41 * Daylight Savings Time to 2 * (24:59:59), just under 50 hours.
42 *
43 *Entry:
44 * __time64_t *ptime - pointer to a long time value
45 *
46 *Exit:
47 * errno_t = 0 success
48 * tm members filled-in
49 * errno_t = non zero
50 * tm members initialized to -1 if ptm != NULL
51 *
52 *Exceptions:
53 * See items (3) and (4) in the NOTES above. If these assumptions are
54 * violated, behavior is undefined.
55 *
56 *******************************************************************************/
57
58 errno_t __cdecl _localtime64_s (
59 struct tm *ptm,
60 const __time64_t *ptime
61 )
62 {
63 __time64_t ltime;
64 errno_t e = 0;
65 int daylight = 0;
66 long dstbias = 0;
67 long timezone = 0;
68
69 _VALIDATE_RETURN_ERRCODE( ( ptm != NULL ), EINVAL )
70 memset( ptm, 0xff, sizeof( struct tm ) );
71
72 _VALIDATE_RETURN_ERRCODE( ( ptime != NULL ), EINVAL )
73
74 /*
75 * Check for illegal __time64_t value
76 */
77 _VALIDATE_RETURN_ERRCODE_NOEXC( (*ptime >= 0), EINVAL);
78 _VALIDATE_RETURN_ERRCODE( (*ptime <= _MAX__TIME64_T), EINVAL);
79
80 __tzset();
81
82 _ERRCHECK(_get_daylight(&daylight));
83 _ERRCHECK(_get_dstbias(&dstbias));
84 _ERRCHECK(_get_timezone(&timezone));
85
86 if ( *ptime > 3 * _DAY_SEC ) {
87 /*
88 * The date does not fall within the first three representable
89 * days of the Epoch. Therefore, there is no possibility of
90 * underflowing the __time64_t representation as we compensate
91 * for timezone and Daylight Savings Time.
92 */
93
94 ltime = *ptime - timezone;
95 e = _gmtime64_s( ptm, <ime );
96 if ( e != 0)
97 {
98 return e;
99 }
100
101 /*
102 * Check and adjust for Daylight Saving Time.
103 */
104 if ( daylight && _isindst( ptm ) ) {
105 ltime -= dstbias;
106 e = _gmtime64_s( ptm, <ime );
107 if ( e != 0 )
108 {
109 return e;
110 }
111 ptm->tm_isdst = 1;
112 }
113 }
114 else {
115 e = _gmtime64_s( ptm, ptime );
116 if ( e != 0 )
117 {
118 return e;
119 }
120
121 /*
122 * The date falls with the first three days of the Epoch.
123 * It is possible the time_t representation would underflow
124 * while compensating for timezone and Daylight Savings Time
125 * Therefore, make the timezone and Daylight Savings Time
126 * adjustments directly in the tm structure. The beginning of
127 * the Epoch is 00:00:00, 01-01-70 (UTC).
128 *
129 * First, adjust for the timezone.
130 */
131 if ( daylight && _isindst(ptm) ) {
132 ltime = (__time64_t)ptm->tm_sec - (timezone + dstbias);
133 ptm->tm_isdst = 1;
134 }
135 else
136 ltime = (__time64_t)ptm->tm_sec - timezone;
137
138 ptm->tm_sec = (int)(ltime % 60);
139 if ( ptm->tm_sec < 0 ) {
140 ptm->tm_sec += 60;
141 ltime -= 60;
142 }
143
144 ltime = (__time64_t)ptm->tm_min + ltime/60;
145 ptm->tm_min = (int)(ltime % 60);
146 if ( ptm->tm_min < 0 ) {
147 ptm->tm_min += 60;
148 ltime -= 60;
149 }
150
151 ltime = (__time64_t)ptm->tm_hour + ltime/60;
152 ptm->tm_hour = (int)(ltime % 24);
153 if ( ptm->tm_hour < 0 ) {
154 ptm->tm_hour += 24;
155 ltime -=24;
156 }
157
158 ltime /= 24;
159
160 if ( ltime < 0 ) {
161 /*
162 * It is possible to underflow the tm_mday and tm_yday
163 * fields. If this happens, then adjusted date must
164 * lie in December 1969.
165 */
166 ptm->tm_wday = (ptm->tm_wday + 7 + (int)ltime) % 7;
167 if ( (ptm->tm_mday += (int)ltime) <= 0 ) {
168 ptm->tm_mday += 31;
169 ptm->tm_yday = 364;
170 ptm->tm_mon = 11;
171 ptm->tm_year--;
172 }
173 else {
174 ptm->tm_yday += (int)ltime;
175 }
176 }
177 }
178
179
180 return 0;
181 }
182
183 /***
184 *struct tm *_localtime64(ptime) - convert __time64_t value to tm structure
185 *
186 *Purpose:
187 * Convert a value in 64-bit internal (__time64_t) format to a tm struct
188 * containing the corresponding local time.
189 *
190 * NOTES:
191 * (1) gmtime must be called before _isindst to ensure that the tb time
192 * structure is initialized.
193 * (2) gmtime, _gtime64, localtime and _localtime64() all use a single
194 * statically allocated buffer. Each call to one of these routines
195 * destroys the contents of the previous call.
196 * (3) It is assumed that __time64_t is a 64-bit integer representing
197 * the number of seconds since 00:00:00, 01-01-70 (UTC) (i.e., the
198 * Posix/Unix Epoch. Only non-negative values are supported.
199 * (4) It is assumed that the maximum adjustment for local time is
200 * less than three days (include Daylight Savings Time adjustment).
201 * This only a concern in Posix where the specification of the TZ
202 * environment restricts the combined offset for time zone and
203 * Daylight Savings Time to 2 * (24:59:59), just under 50 hours.
204 *
205 *Entry:
206 * __time64_t *ptime - pointer to a long time value
207 *
208 *Exit:
209 * If *ptime is non-negative, returns a pointer to the tm structure.
210 * Otherwise, returns NULL.
211 *
212 *Exceptions:
213 * See items (3) and (4) in the NOTES above. If these assumptions are
214 * violated, behavior is undefined.
215 *
216 *******************************************************************************/
217
218 struct tm * __cdecl _localtime64 (
219 const __time64_t *ptime
220 )
221 {
222 errno_t e;
223 struct tm *ptm = __getgmtimebuf();
224 if ( ptm == NULL )
225 {
226 return NULL;
227 }
228
229 e = _localtime64_s( ptm, ptime );
230 if ( e != 0 )
231 {
232 return NULL;
233 }
234 return ptm;
235 }
在这段代码中,展示了文件注释,函数注释,区块注释,参数对齐,变量命名和错误处理等方面的格式,虽然在括号对其方面有一些不一致的情况,很明显是不同作者写的,但是还是很好的保持了清晰的版式,很值得我们学习。
下面这个链接是关于安全编程的,2004的文章,现在看看觉得很有体会:
http://www.microsoft.com/china/msdn/library/security/secure03102004.mspx?mfr=true