ReactOS 0.4.16-dev-981-g80eb313
time.c
Go to the documentation of this file.
1/*
2 * Unit test suite for time functions.
3 *
4 * Copyright 2004 Uwe Bonnes
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "wine/test.h"
22#include "winbase.h"
23#include "winnls.h"
24#include "time.h"
25
26#include <stdlib.h> /*setenv*/
27#include <stdio.h> /*printf*/
28#include <locale.h>
29#include <errno.h>
30
31#define _MAX__TIME64_T (((__time64_t)0x00000007 << 32) | 0x93406FFF)
32
33#define SECSPERDAY 86400
34#define SECSPERHOUR 3600
35#define SECSPERMIN 60
36#define MINSPERHOUR 60
37#define HOURSPERDAY 24
38
39typedef struct {
40 const char *short_wday[7];
41 const char *wday[7];
42 const char *short_mon[12];
43 const char *mon[12];
44 const char *am;
45 const char *pm;
46 const char *short_date;
47 const char *date;
48 const char *time;
50 int unk;
53
54static __time32_t (__cdecl *p_mkgmtime32)(struct tm*);
55static struct tm* (__cdecl *p_gmtime32)(__time32_t*);
56static struct tm* (__cdecl *p_gmtime)(time_t*);
57static errno_t (__cdecl *p_gmtime32_s)(struct tm*, __time32_t*);
58static struct tm* (__cdecl *p_gmtime64)(__time64_t*);
59static errno_t (__cdecl *p_gmtime64_s)(struct tm*, __time64_t*);
60static errno_t (__cdecl *p_strtime_s)(char*,size_t);
61static errno_t (__cdecl *p_strdate_s)(char*,size_t);
62static errno_t (__cdecl *p_localtime32_s)(struct tm*, __time32_t*);
63static errno_t (__cdecl *p_localtime64_s)(struct tm*, __time64_t*);
64static int* (__cdecl *p__daylight)(void);
65static int* (__cdecl *p___p__daylight)(void);
66static long* (__cdecl *p___p__dstbias)(void);
67static long* (__cdecl *p__dstbias)(void);
68static long* (__cdecl *p___p__timezone)(void);
69static size_t (__cdecl *p_strftime)(char *, size_t, const char *, const struct tm *);
70static size_t (__cdecl *p__Strftime)(char*, size_t, const char*, const struct tm*, void*);
71static size_t (__cdecl *p_wcsftime)(wchar_t *, size_t, const wchar_t *, const struct tm *);
72static char* (__cdecl *p_asctime)(const struct tm *);
73
74static void init(void)
75{
76 HMODULE hmod = LoadLibraryA("msvcrt.dll");
77
78 p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32");
79 p_gmtime = (void*)GetProcAddress(hmod, "gmtime");
80 p_gmtime32_s = (void*)GetProcAddress(hmod, "_gmtime32_s");
81 p_gmtime64 = (void*)GetProcAddress(hmod, "_gmtime64");
82 p_gmtime64_s = (void*)GetProcAddress(hmod, "_gmtime64_s");
83 p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32");
84 p_strtime_s = (void*)GetProcAddress(hmod, "_strtime_s");
85 p_strdate_s = (void*)GetProcAddress(hmod, "_strdate_s");
86 p_localtime32_s = (void*)GetProcAddress(hmod, "_localtime32_s");
87 p_localtime64_s = (void*)GetProcAddress(hmod, "_localtime64_s");
88 p__daylight = (void*)GetProcAddress(hmod, "__daylight");
89 p___p__daylight = (void*)GetProcAddress(hmod, "__p__daylight");
90 p___p__dstbias = (void*)GetProcAddress(hmod, "__p__dstbias");
91 p__dstbias = (void*)GetProcAddress(hmod, "__dstbias");
92 p___p__timezone = (void*)GetProcAddress(hmod, "__p__timezone");
93 p_strftime = (void*)GetProcAddress(hmod, "strftime");
94 p__Strftime = (void*)GetProcAddress(hmod, "_Strftime");
95 p_wcsftime = (void*)GetProcAddress(hmod, "wcsftime");
96 p_asctime = (void*)GetProcAddress(hmod, "asctime");
97}
98
100{
101 time_t now = time(NULL);
102 struct tm *tm = localtime(&now);
103
104 /* compute start of year in seconds */
105 *start = SECSPERDAY * ((tm->tm_year - 70) * 365 +
106 (tm->tm_year - 69) / 4 -
107 (tm->tm_year - 1) / 100 +
108 (tm->tm_year + 299) / 400);
109 return tm->tm_year;
110}
111
112static void test_ctime(void)
113{
114 time_t badtime = -1;
115 char* ret;
116 ret = ctime(&badtime);
117 ok(ret == NULL, "expected ctime to return NULL, got %s\n", ret);
118}
119static void test_gmtime(void)
120{
121 __time32_t valid, gmt;
122 struct tm* gmt_tm, gmt_tm_s;
123 errno_t err;
124
125 if(!p_gmtime32) {
126 win_skip("Skipping _gmtime32 tests\n");
127 return;
128 }
129
130 gmt_tm = p_gmtime32(NULL);
131 ok(gmt_tm == NULL, "gmt_tm != NULL\n");
132
133 gmt = -1;
134 gmt_tm = p_gmtime32(&gmt);
135 ok(gmt_tm==NULL || broken(gmt_tm->tm_year==70 && gmt_tm->tm_sec<0), "gmt_tm != NULL\n");
136
137 gmt = valid = 0;
138 gmt_tm = p_gmtime32(&gmt);
139 if(!gmt_tm) {
140 ok(0, "_gmtime32() failed\n");
141 return;
142 }
143
144 ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon == 0) && (gmt_tm->tm_yday == 0) &&
145 (gmt_tm->tm_mday == 1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour == 0) &&
146 (gmt_tm->tm_min == 0) && (gmt_tm->tm_sec == 0) && (gmt_tm->tm_isdst == 0)),
147 "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
148 gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday,
149 gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst);
150
151 if(!p_mkgmtime32) {
152 win_skip("Skipping _mkgmtime32 tests\n");
153 return;
154 }
155
156 gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
157 gmt = p_mkgmtime32(gmt_tm);
158 ok(gmt == valid, "gmt = %lu\n", gmt);
159 ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
160 ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
161
162 gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
163 gmt_tm->tm_isdst = -1;
164 gmt = p_mkgmtime32(gmt_tm);
165 ok(gmt == valid, "gmt = %lu\n", gmt);
166 ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
167 ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
168
169 gmt_tm->tm_wday = gmt_tm->tm_yday = 0;
170 gmt_tm->tm_isdst = 1;
171 gmt = p_mkgmtime32(gmt_tm);
172 ok(gmt == valid, "gmt = %lu\n", gmt);
173 ok(gmt_tm->tm_wday == 4, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
174 ok(gmt_tm->tm_yday == 0, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
175
176 gmt = valid = 173921;
177 gmt_tm = p_gmtime32(&gmt);
178 if(!gmt_tm) {
179 ok(0, "_gmtime32() failed\n");
180 return;
181 }
182
183 gmt_tm->tm_isdst = -1;
184 gmt = p_mkgmtime32(gmt_tm);
185 ok(gmt == valid, "gmt = %lu\n", gmt);
186 ok(gmt_tm->tm_wday == 6, "gmt_tm->tm_wday = %d\n", gmt_tm->tm_wday);
187 ok(gmt_tm->tm_yday == 2, "gmt_tm->tm_yday = %d\n", gmt_tm->tm_yday);
188
189 gmt_tm->tm_isdst = 1;
190 gmt = p_mkgmtime32(gmt_tm);
191 ok(gmt == valid, "gmt = %lu\n", gmt);
192
193 if(!p_gmtime32_s) {
194 win_skip("Skipping _gmtime32_s tests\n");
195 return;
196 }
197
198 errno = 0;
199 gmt = 0;
200 err = p_gmtime32_s(NULL, &gmt);
201 ok(err == EINVAL, "err = %d\n", err);
202 ok(errno == EINVAL, "errno = %d\n", errno);
203
204 errno = 0;
205 gmt = -1;
206 err = p_gmtime32_s(&gmt_tm_s, &gmt);
207 ok(gmt_tm_s.tm_year == -1 || broken(gmt_tm_s.tm_year == 70 && gmt_tm_s.tm_sec < 0),
208 "tm_year = %d, tm_sec = %d\n", gmt_tm_s.tm_year, gmt_tm_s.tm_sec);
209 if(gmt_tm_s.tm_year == -1) {
210 ok(err==EINVAL, "err = %d\n", err);
211 ok(errno==EINVAL, "errno = %d\n", errno);
212 }
213}
214
215static void test_gmtime64(void)
216{
217 struct tm *ptm, tm;
219 int ret;
220
221 t = -1;
222 memset(&tm, 0xcc, sizeof(tm));
223 ptm = p_gmtime64(&t);
224 if (!ptm)
225 {
226 skip("Old gmtime64 limits, skipping tests.\n");
227 return;
228 }
229 ok(!!ptm, "got NULL.\n");
230 ret = p_gmtime64_s(&tm, &t);
231 ok(!ret, "got %d.\n", ret);
232 ok(tm.tm_year == 69 && tm.tm_hour == 23 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n",
234
235 t = -43200;
236 memset(&tm, 0xcc, sizeof(tm));
237 ptm = p_gmtime64(&t);
238 ok(!!ptm, "got NULL.\n");
239 ret = p_gmtime64_s(&tm, &t);
240 ok(!ret, "got %d.\n", ret);
241 ok(tm.tm_year == 69 && tm.tm_hour == 12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n",
243 ptm = p_gmtime32((__time32_t *)&t);
244 ok(!!ptm, "got NULL.\n");
245 memset(&tm, 0xcc, sizeof(tm));
246 ret = p_gmtime32_s(&tm, (__time32_t *)&t);
247 ok(!ret, "got %d.\n", ret);
248 todo_wine_if(tm.tm_year == 69 && tm.tm_hour == 12)
249 ok(tm.tm_year == 70 && tm.tm_hour == -12 && tm.tm_min == 0 && tm.tm_sec == 0, "got %d, %d, %d, %d.\n",
251
252 t = -43201;
253 ptm = p_gmtime64(&t);
254 ok(!ptm, "got non-NULL.\n");
255 memset(&tm, 0xcc, sizeof(tm));
256 ret = p_gmtime64_s(&tm, &t);
257 ok(ret == EINVAL, "got %d.\n", ret);
258 ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n",
260 ptm = p_gmtime32((__time32_t *)&t);
261 ok(!ptm, "got NULL.\n");
262 memset(&tm, 0xcc, sizeof(tm));
263 ret = p_gmtime32_s(&tm, (__time32_t *)&t);
264 ok(ret == EINVAL, "got %d.\n", ret);
265 ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n",
267
268 t = _MAX__TIME64_T + 46800;
269 memset(&tm, 0xcc, sizeof(tm));
270 ptm = p_gmtime64(&t);
271 ok(!!ptm, "got NULL.\n");
272 ret = p_gmtime64_s(&tm, &t);
273 ok(!ret, "got %d.\n", ret);
274 ok(tm.tm_year == 1101 && tm.tm_hour == 20 && tm.tm_min == 59 && tm.tm_sec == 59, "got %d, %d, %d, %d.\n",
276
277 t = _MAX__TIME64_T + 46801;
278 ptm = p_gmtime64(&t);
279 ok(!ptm, "got non-NULL.\n");
280 memset(&tm, 0xcc, sizeof(tm));
281 ret = p_gmtime64_s(&tm, &t);
282 ok(ret == EINVAL, "got %d.\n", ret);
283 ok(tm.tm_year == -1 && tm.tm_hour == -1 && tm.tm_min == -1 && tm.tm_sec == -1, "got %d, %d, %d, %d.\n",
285}
286
287static void test_mktime(void)
288{
291 struct tm my_tm, sav_tm;
292 time_t nulltime, local_time;
293 char TZ_env[256];
294 char buffer[64];
295 int year;
296 time_t ref, secs;
297
298 year = get_test_year( &ref );
299 ref += SECSPERDAY;
300
301 ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
302 WideCharToMultiByte( CP_ACP, 0, tzinfo.StandardName, -1, buffer, sizeof(buffer), NULL, NULL );
303 trace( "bias %ld std %ld dst %ld zone %s\n",
304 tzinfo.Bias, tzinfo.StandardBias, tzinfo.DaylightBias, buffer );
305 /* Bias may be positive or negative, to use offset of one day */
306 my_tm = *localtime(&ref); /* retrieve current dst flag */
307 secs = SECSPERDAY - tzinfo.Bias * SECSPERMIN;
308 secs -= (my_tm.tm_isdst ? tzinfo.DaylightBias : tzinfo.StandardBias) * SECSPERMIN;
309 my_tm.tm_mday = 1 + secs/SECSPERDAY;
310 secs = secs % SECSPERDAY;
311 my_tm.tm_hour = secs / SECSPERHOUR;
312 secs = secs % SECSPERHOUR;
313 my_tm.tm_min = secs / SECSPERMIN;
314 secs = secs % SECSPERMIN;
315 my_tm.tm_sec = secs;
316
317 my_tm.tm_year = year;
318 my_tm.tm_mon = 0;
319
320 sav_tm = my_tm;
321
322 local_time = mktime(&my_tm);
323 ok(local_time == ref, "mktime returned %lu, expected %lu\n",
325 /* now test some unnormalized struct tm's */
326 my_tm = sav_tm;
327 my_tm.tm_sec += 60;
328 my_tm.tm_min -= 1;
329 local_time = mktime(&my_tm);
330 ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n",
332 ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
333 my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
334 my_tm.tm_sec == sav_tm.tm_sec,
335 "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
336 my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
337 my_tm.tm_hour,my_tm.tm_sec,
338 sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
339 sav_tm.tm_hour,sav_tm.tm_sec);
340 my_tm = sav_tm;
341 my_tm.tm_min -= 60;
342 my_tm.tm_hour += 1;
343 local_time = mktime(&my_tm);
344 ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n",
346 ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
347 my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
348 my_tm.tm_sec == sav_tm.tm_sec,
349 "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
350 my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
351 my_tm.tm_hour,my_tm.tm_sec,
352 sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
353 sav_tm.tm_hour,sav_tm.tm_sec);
354 my_tm = sav_tm;
355 my_tm.tm_mon -= 12;
356 my_tm.tm_year += 1;
357 local_time = mktime(&my_tm);
358 ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n",
360 ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
361 my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
362 my_tm.tm_sec == sav_tm.tm_sec,
363 "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
364 my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
365 my_tm.tm_hour,my_tm.tm_sec,
366 sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
367 sav_tm.tm_hour,sav_tm.tm_sec);
368 my_tm = sav_tm;
369 my_tm.tm_mon += 12;
370 my_tm.tm_year -= 1;
371 local_time = mktime(&my_tm);
372 ok(local_time == ref, "Unnormalized mktime returned %lu, expected %lu\n",
374 ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
375 my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
376 my_tm.tm_sec == sav_tm.tm_sec,
377 "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
378 my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
379 my_tm.tm_hour,my_tm.tm_sec,
380 sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
381 sav_tm.tm_hour,sav_tm.tm_sec);
382 /* now a bad time example */
383 my_tm = sav_tm;
384 my_tm.tm_year = 69;
385 local_time = mktime(&my_tm);
386 ok((local_time == -1), "(bad time) mktime returned %d, expected -1\n", (int)local_time);
387
388 my_tm = sav_tm;
389 /* TEST that we are independent from the TZ variable */
390 /*Argh, msvcrt doesn't have setenv() */
391 _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
392 putenv("TZ=GMT");
393 nulltime = mktime(&my_tm);
394 ok(nulltime == ref,"mktime returned 0x%08lx\n",(DWORD)nulltime);
395 putenv(TZ_env);
396}
397
398static void test_localtime(void)
399{
402 time_t gmt, ref;
403
404 char TZ_env[256];
405 struct tm* lt;
406 int year = get_test_year( &ref );
407 int is_leap = !(year % 4) && ((year % 100) || !((year + 300) % 400));
408
409 gmt = ref + SECSPERDAY + tzinfo.Bias * SECSPERMIN;
410 ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
411 lt = localtime(&gmt);
412 gmt += (lt->tm_isdst ? tzinfo.DaylightBias : tzinfo.StandardBias) * SECSPERMIN;
413 lt = localtime(&gmt);
414 ok(((lt->tm_year == year) && (lt->tm_mon == 0) && (lt->tm_yday == 1) &&
415 (lt->tm_mday == 2) && (lt->tm_hour == 0) &&
416 (lt->tm_min == 0) && (lt->tm_sec == 0)),
417 "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
418 lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour,
419 lt->tm_min, lt->tm_sec, lt->tm_isdst);
420
421 _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
422 putenv("TZ=GMT");
423 lt = localtime(&gmt);
424 ok(((lt->tm_year == year) && (lt->tm_mon == 0) && (lt->tm_yday == 1) &&
425 (lt->tm_mday == 2) && (lt->tm_hour == 0) &&
426 (lt->tm_min == 0) && (lt->tm_sec == 0)),
427 "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
428 lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour,
429 lt->tm_min, lt->tm_sec, lt->tm_isdst);
430 putenv(TZ_env);
431
432 /* June 22 */
433 gmt = ref + 202 * SECSPERDAY + tzinfo.Bias * SECSPERMIN;
434 lt = localtime(&gmt);
435 gmt += (lt->tm_isdst ? tzinfo.DaylightBias : tzinfo.StandardBias) * SECSPERMIN;
436 lt = localtime(&gmt);
437 ok(((lt->tm_year == year) && (lt->tm_mon == 6) && (lt->tm_yday == 202) &&
438 (lt->tm_mday == 22 - is_leap) && (lt->tm_hour == 0) &&
439 (lt->tm_min == 0) && (lt->tm_sec == 0)),
440 "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
441 lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour,
442 lt->tm_min, lt->tm_sec, lt->tm_isdst);
443}
444
445static void test_strdate(void)
446{
447 char date[16], * result;
448 int month, day, year, count, len;
449 errno_t err;
450
452 ok(result == date, "Wrong return value\n");
453 len = strlen(date);
454 ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
455 count = sscanf(date, "%02d/%02d/%02d", &month, &day, &year);
456 ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
457
458 if(!p_strdate_s) {
459 win_skip("Skipping _strdate_s tests\n");
460 return;
461 }
462
463 errno = 0;
464 err = p_strdate_s(NULL, 1);
465 ok(err == EINVAL, "err = %d\n", err);
466 ok(errno == EINVAL, "errno = %d\n", errno);
467
468 date[0] = 'x';
469 date[1] = 'x';
470 err = p_strdate_s(date, 8);
471 ok(err == ERANGE, "err = %d\n", err);
472 ok(errno == ERANGE, "errno = %d\n", errno);
473 ok(date[0] == '\0', "date[0] != '\\0'\n");
474 ok(date[1] == 'x', "date[1] != 'x'\n");
475
476 err = p_strdate_s(date, 9);
477 ok(err == 0, "err = %x\n", err);
478}
479
480static void test_strtime(void)
481{
482 char time[16], * result;
483 int hour, minute, second, count, len;
484 errno_t err;
485
487 ok(result == time, "Wrong return value\n");
488 len = strlen(time);
489 ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
490 count = sscanf(time, "%02d:%02d:%02d", &hour, &minute, &second);
491 ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
492
493 if(!p_strtime_s) {
494 win_skip("Skipping _strtime_s tests\n");
495 return;
496 }
497
498 errno = 0;
499 err = p_strtime_s(NULL, 0);
500 ok(err == EINVAL, "err = %d\n", err);
501 ok(errno == EINVAL, "errno = %d\n", errno);
502
503 err = p_strtime_s(NULL, 1);
504 ok(err == EINVAL, "err = %d\n", err);
505 ok(errno == EINVAL, "errno = %d\n", errno);
506
507 time[0] = 'x';
508 err = p_strtime_s(time, 8);
509 ok(err == ERANGE, "err = %d\n", err);
510 ok(errno == ERANGE, "errno = %d\n", errno);
511 ok(time[0] == '\0', "time[0] != '\\0'\n");
512
513 err = p_strtime_s(time, 9);
514 ok(err == 0, "err = %x\n", err);
515}
516
517static void test_wstrdate(void)
518{
519 wchar_t date[16], * result;
520 int month, day, year, count, len;
521
523 ok(result == date, "Wrong return value\n");
524 len = wcslen(date);
525 ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
526 count = swscanf(date, L"%02d/%02d/%02d", &month, &day, &year);
527 ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
528}
529
530static void test_wstrtime(void)
531{
532 wchar_t time[16], * result;
533 int hour, minute, second, count, len;
534
536 ok(result == time, "Wrong return value\n");
537 len = wcslen(time);
538 ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
539 count = swscanf(time, L"%02d:%02d:%02d", &hour, &minute, &second);
540 ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
541}
542
543static void test_localtime32_s(void)
544{
545 struct tm tm;
547 errno_t err;
548
549 if (!p_localtime32_s)
550 {
551 win_skip("Skipping _localtime32_s tests\n");
552 return;
553 }
554
555 errno = EBADF;
556 err = p_localtime32_s(NULL, NULL);
557 ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err);
558 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
559
560 errno = EBADF;
561 time = 0x12345678;
562 err = p_localtime32_s(NULL, &time);
563 ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err);
564 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
565
566 memset(&tm, 0, sizeof(tm));
567 errno = EBADF;
568 err = p_localtime32_s(&tm, NULL);
569 ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err);
570 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
571 ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 &&
572 tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 &&
573 tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1,
574 "Expected tm structure members to be initialized to -1, got "
575 "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min,
577 tm.tm_isdst);
578
579 memset(&tm, 0, sizeof(tm));
580 time = -1;
581 errno = EBADF;
582 err = p_localtime32_s(&tm, &time);
583 ok(err == EINVAL, "Expected _localtime32_s to return EINVAL, got %d\n", err);
584 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
585 ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 &&
586 tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 &&
587 tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1,
588 "Expected tm structure members to be initialized to -1, got "
589 "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min,
591 tm.tm_isdst);
592}
593
594static void test_localtime64_s(void)
595{
596 struct tm tm;
598 errno_t err;
599
600 if (!p_localtime64_s)
601 {
602 win_skip("Skipping _localtime64_s tests\n");
603 return;
604 }
605
606 errno = EBADF;
607 err = p_localtime64_s(NULL, NULL);
608 ok(err == EINVAL, "Expected _localtime64_s to return EINVAL, got %d\n", err);
609 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
610
611 errno = EBADF;
612 time = 0xdeadbeef;
613 err = p_localtime64_s(NULL, &time);
614 ok(err == EINVAL, "Expected _localtime64_s to return EINVAL, got %d\n", err);
615 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
616
617 memset(&tm, 0, sizeof(tm));
618 errno = EBADF;
619 err = p_localtime64_s(&tm, NULL);
620 ok(err == EINVAL, "Expected _localtime64_s to return EINVAL, got %d\n", err);
621 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
622 ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 &&
623 tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 &&
624 tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1,
625 "Expected tm structure members to be initialized to -1, got "
626 "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min,
628 tm.tm_isdst);
629
630 memset(&tm, 0, sizeof(tm));
631 time = -1;
632 errno = EBADF;
633 err = p_localtime64_s(&tm, &time);
634 ok(err == EINVAL, "Expected _localtime64_s to return EINVAL, got %d\n", err);
635 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
636 ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 &&
637 tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 &&
638 tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1,
639 "Expected tm structure members to be initialized to -1, got "
640 "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min,
642 tm.tm_isdst);
643
644 memset(&tm, 0, sizeof(tm));
645 time = _MAX__TIME64_T + 1;
646 errno = EBADF;
647 err = p_localtime64_s(&tm, &time);
648 ok(err == EINVAL, "Expected _localtime64_s to return EINVAL, got %d\n", err);
649 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
650 ok(tm.tm_sec == -1 && tm.tm_min == -1 && tm.tm_hour == -1 &&
651 tm.tm_mday == -1 && tm.tm_mon == -1 && tm.tm_year == -1 &&
652 tm.tm_wday == -1 && tm.tm_yday == -1 && tm.tm_isdst == -1,
653 "Expected tm structure members to be initialized to -1, got "
654 "(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", tm.tm_sec, tm.tm_min,
656 tm.tm_isdst);
657}
658
659static void test_daylight(void)
660{
661 int *ret1, *ret2;
662
663 if (!p__daylight)
664 {
665 win_skip("__daylight() not available\n");
666 return;
667 }
668
669 /* Examine the returned pointer from __p__environ(), if available. */
670 if (sizeof(void*) != sizeof(int))
671 ok( !p___p__daylight, "___p__daylight() should be 32-bit only\n");
672 else
673 {
674 ret1 = p__daylight();
675 ret2 = p___p__daylight();
676 ok(ret1 && ret1 == ret2, "got %p\n", ret1);
677 }
678}
679
680static void test_strftime(void)
681{
682 const struct {
683 const char *format;
684 } tests_einval[] = {
685 {"%C"},
686 {"%D"},
687 {"%e"},
688 {"%F"},
689 {"%h"},
690 {"%n"},
691 {"%R"},
692 {"%t"},
693 {"%T"},
694 {"%u"},
695 };
696
697 const struct {
698 const char *format;
699 const char *ret;
700 struct tm tm;
701 BOOL todo;
702 } tests[] = {
703 {"e%#%e", "e%e", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
704 {"%c", "01/01/70 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
705 {"%c", "02/30/70 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }},
706 {"%#c", "Thursday, January 01, 1970 00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
707 {"%#c", "Thursday, February 30, 1970 00:00:00", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }},
708 {"%x", "01/01/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
709 {"%x", "02/30/70", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }},
710 {"%#x", "Thursday, January 01, 1970", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
711 {"%#x", "Thursday, February 30, 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }},
712 {"%X", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
713 {"%X", "14:00:00", { 0, 0, 14, 1, 0, 70, 4, 0, 0 }},
714 {"%a", "Thu", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
715 {"%A", "Thursday", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
716 {"%b", "Jan", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
717 {"%B", "January", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
718 {"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
719 {"%#d", "1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
720 {"%H", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
721 {"%I", "12", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
722 {"%j", "001", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
723 {"%m", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
724 {"%#M", "0", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
725 {"%p", "AM", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
726 {"%U", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
727 {"%W", "00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
728 {"%U", "01", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
729 {"%W", "00", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
730 {"%U", "53", { 0, 0, 0, 1, 0, 70, 0, 365, 0 }},
731 {"%W", "52", { 0, 0, 0, 1, 0, 70, 0, 365, 0 }},
732 };
733
734 const struct {
735 const char *format;
736 const char *ret;
737 const char *short_date;
738 const char *date;
739 const char *time;
740 struct tm tm;
741 BOOL todo;
742 } tests_td[] = {
743 { "%c", "x z", "x", "y", "z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
744 { "%#c", "y z", "x", "y", "z", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
745 { "%X", "m1", 0, 0, "MMM", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
746 { "%X", "1", 0, 0, "h", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
747 { "%X", "01", 0, 0, "hh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
748 { "%X", "h01", 0, 0, "hhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
749 { "%X", "hh01", 0, 0, "hhhh", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
750 { "%X", "1", 0, 0, "H", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
751 { "%X", "01", 0, 0, "HH", { 0, 0, 1, 1, 0, 70, 0, 0, 0 }},
752 { "%X", "H13", 0, 0, "HHH", { 0, 0, 13, 1, 0, 70, 0, 0, 0 }},
753 { "%X", "0", 0, 0, "m", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
754 { "%X", "00", 0, 0, "mm", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
755 { "%X", "0", 0, 0, "s", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
756 { "%X", "00", 0, 0, "ss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
757 { "%X", "s00", 0, 0, "sss", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
758 { "%X", "t", 0, 0, "t", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
759 { "%X", "tam", 0, 0, "tt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
760 { "%X", "tam", 0, 0, "ttttttttt", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
761 { "%X", "tam", 0, 0, "a", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
762 { "%X", "tam", 0, 0, "aaaaa", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
763 { "%X", "tam", 0, 0, "A", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
764 { "%X", "tam", 0, 0, "AAAAA", { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
765 { "%x", "1", "d", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
766 { "%x", "01", "dd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
767 { "%x", "d1", "ddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
768 { "%x", "day1", "dddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
769 { "%x", "dday1", "ddddd", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
770 { "%x", "1", "M", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
771 { "%x", "01", "MM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
772 { "%x", "m1", "MMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
773 { "%x", "mon1", "MMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
774 { "%x", "Mmon1", "MMMMM", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
775 { "%x", "y", "y", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
776 { "%x", "70", "yy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
777 { "%x", "y70", "yyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
778 { "%x", "1970", "yyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
779 { "%x", "y1970", "yyyyy", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
780 { "%x", "ggggggggggg", "ggggggggggg", 0, 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
781 { "%#x", "1", 0, "d", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
782 { "%#x", "01", 0, "dd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
783 { "%#x", "d1", 0, "ddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
784 { "%#x", "day1", 0, "dddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
785 { "%#x", "dday1", 0, "ddddd", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
786 { "%#x", "1", 0, "M", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
787 { "%#x", "01", 0, "MM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
788 { "%#x", "m1", 0, "MMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
789 { "%#x", "mon1", 0, "MMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
790 { "%#x", "Mmon1", 0, "MMMMM", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
791 { "%#x", "y", 0, "y", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
792 { "%#x", "70", 0, "yy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
793 { "%#x", "y70", 0, "yyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
794 { "%#x", "1970", 0, "yyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
795 { "%#x", "y1970", 0, "yyyyy", 0, { 0, 0, 0, 1, 0, 70, 0, 0, 0 }},
796 };
797
798 __lc_time_data time_data = {
799 { "d1", "d2", "d3", "d4", "d5", "d6", "d7" },
800 { "day1", "day2", "day3", "day4", "day5", "day6", "day7" },
801 { "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10", "m11", "m12" },
802 { "mon1", "mon2", "mon3", "mon4", "mon5", "mon6", "mon7", "mon8", "mon9", "mon10", "mon11", "mon12" },
803 "tam", "tpm"
804 };
805 time_t gmt;
806 struct tm* gmt_tm;
807 char buf[256], bufA[256];
808 WCHAR bufW[256];
809 long retA, retW;
810 int i;
811
812 if (!p_strftime || !p_wcsftime || !p_gmtime)
813 {
814 win_skip("strftime, wcsftime or gmtime is not available\n");
815 return;
816 }
817
818 setlocale(LC_TIME, "C");
819
820 gmt = 0;
821 gmt_tm = p_gmtime(&gmt);
822 ok(gmt_tm != NULL, "gmtime failed\n");
823
824 for (i=0; i<ARRAY_SIZE(tests_einval); i++)
825 {
826 errno = 0xdeadbeef;
827 retA = p_strftime(bufA, 256, tests_einval[i].format, gmt_tm);
828 ok(retA == 0, "%d) ret = %ld\n", i, retA);
829 ok(errno==EINVAL || broken(errno==0xdeadbeef), "%d) errno = %d\n", i, errno);
830 }
831
832 errno = 0xdeadbeef;
833 retA = p_strftime(NULL, 0, "copy", gmt_tm);
834 ok(retA == 0, "expected 0, got %ld\n", retA);
835 ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
836
837 retA = p_strftime(bufA, 256, "copy", NULL);
838 ok(retA == 4, "expected 4, got %ld\n", retA);
839 ok(!strcmp(bufA, "copy"), "got %s\n", bufA);
840
841 retA = p_strftime(bufA, 256, "copy it", gmt_tm);
842 ok(retA == 7, "expected 7, got %ld\n", retA);
843 ok(!strcmp(bufA, "copy it"), "got %s\n", bufA);
844
845 errno = 0xdeadbeef;
846 retA = p_strftime(bufA, 2, "copy", gmt_tm);
847 ok(retA == 0, "expected 0, got %ld\n", retA);
848 ok(!strcmp(bufA, "") || broken(!strcmp(bufA, "copy it")), "got %s\n", bufA);
849 ok(errno==ERANGE || errno==0xdeadbeef, "errno = %d\n", errno);
850
851 errno = 0xdeadbeef;
852 retA = p_strftime(bufA, 256, "a%e", gmt_tm);
853 ok(retA==0 || broken(retA==1), "expected 0, got %ld\n", retA);
854 ok(!strcmp(bufA, "") || broken(!strcmp(bufA, "a")), "got %s\n", bufA);
855 ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
856
857 if(0) { /* crashes on Win2k */
858 errno = 0xdeadbeef;
859 retA = p_strftime(bufA, 256, "%c", NULL);
860 ok(retA == 0, "expected 0, got %ld\n", retA);
861 ok(!strcmp(bufA, ""), "got %s\n", bufA);
862 ok(errno == EINVAL, "errno = %d\n", errno);
863 }
864
865 for (i=0; i<ARRAY_SIZE(tests); i++)
866 {
867 retA = p_strftime(bufA, 256, tests[i].format, &tests[i].tm);
869 ok(retA == strlen(tests[i].ret), "%d) ret = %ld\n", i, retA);
870 ok(!strcmp(bufA, tests[i].ret), "%d) buf = \"%s\", expected \"%s\"\n",
871 i, bufA, tests[i].ret);
872 }
873 }
874
875 retA = p_strftime(bufA, 256, "%c", gmt_tm);
876 retW = p_wcsftime(bufW, 256, L"%c", gmt_tm);
877 ok(retW == 17, "expected 17, got %ld\n", retW);
878 ok(retA == retW, "expected %ld, got %ld\n", retA, retW);
879 buf[0] = 0;
880 retA = WideCharToMultiByte(CP_ACP, 0, bufW, retW, buf, 256, NULL, NULL);
881 buf[retA] = 0;
882 ok(strcmp(bufA, buf) == 0, "expected %s, got %s\n", bufA, buf);
883
884 if(!setlocale(LC_ALL, "Japanese_Japan.932")) {
885 win_skip("Japanese_Japan.932 locale not available\n");
886 return;
887 }
888
889 /* test with multibyte character */
890 retA = p_strftime(bufA, 256, "\x82%c", gmt_tm);
891 ok(retA == 3, "expected 3, got %ld\n", retA);
892 ok(!strcmp(bufA, "\x82%c"), "got %s\n", bufA);
893
894 setlocale(LC_ALL, "C");
895 if(!p__Strftime) {
896 win_skip("_Strftime is not available\n");
897 return;
898 }
899
900 /* TODO: find meaning of unk */
901 time_data.unk = 1;
902 for (i=0; i<ARRAY_SIZE(tests_td); i++)
903 {
904 time_data.short_date = tests_td[i].short_date;
905 time_data.date = tests_td[i].date;
906 time_data.time = tests_td[i].time;
907 retA = p__Strftime(buf, sizeof(buf), tests_td[i].format, &tests_td[i].tm, &time_data);
908 ok(retA == strlen(buf), "%d) ret = %ld\n", i, retA);
909 todo_wine_if(tests_td[i].todo) {
910 ok(!strcmp(buf, tests_td[i].ret), "%d) buf = \"%s\", expected \"%s\"\n",
911 i, buf, tests_td[i].ret);
912 }
913 }
914}
915
916static void test_asctime(void)
917{
918 struct tm* gmt_tm;
919 time_t gmt;
920 char *ret;
921
922 if(!p_asctime || !p_gmtime)
923 {
924 win_skip("asctime or gmtime is not available\n");
925 return;
926 }
927
928 gmt = 0;
929 gmt_tm = p_gmtime(&gmt);
930 ret = p_asctime(gmt_tm);
931 ok(!strcmp(ret, "Thu Jan 01 00:00:00 1970\n"), "asctime returned %s\n", ret);
932
933 gmt = 312433121;
934 gmt_tm = p_gmtime(&gmt);
935 ret = p_asctime(gmt_tm);
936 ok(!strcmp(ret, "Mon Nov 26 02:58:41 1979\n"), "asctime returned %s\n", ret);
937
938 /* Week day is only checked if it's in 0..6 range */
939 gmt_tm->tm_wday = 3;
940 ret = p_asctime(gmt_tm);
941 ok(!strcmp(ret, "Wed Nov 26 02:58:41 1979\n"), "asctime returned %s\n", ret);
942
943 errno = 0xdeadbeef;
944 gmt_tm->tm_wday = 7;
945 ret = p_asctime(gmt_tm);
946 ok(!ret || broken(!ret[0]), "asctime returned %s\n", ret);
947 ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
948
949 /* Year day is ignored */
950 gmt_tm->tm_wday = 3;
951 gmt_tm->tm_yday = 1300;
952 ret = p_asctime(gmt_tm);
953 ok(!strcmp(ret, "Wed Nov 26 02:58:41 1979\n"), "asctime returned %s\n", ret);
954
955 /* Dates that can't be displayed using 26 characters are broken */
956 gmt_tm->tm_mday = 28;
957 gmt_tm->tm_year = 8100;
958 ret = p_asctime(gmt_tm);
959 ok(!strcmp(ret, "Wed Nov 28 02:58:41 :000\n"), "asctime returned %s\n", ret);
960
961 gmt_tm->tm_year = 264100;
962 ret = p_asctime(gmt_tm);
963 ok(!strcmp(ret, "Wed Nov 28 02:58:41 :000\n"), "asctime returned %s\n", ret);
964
965 /* asctime works from year 1900 */
966 errno = 0xdeadbeef;
967 gmt_tm->tm_year = -1;
968 ret = p_asctime(gmt_tm);
969 ok(!ret || broken(!strcmp(ret, "Wed Nov 28 02:58:41 190/\n")), "asctime returned %s\n", ret);
970 ok(errno==EINVAL || broken(errno == 0xdeadbeef), "errno = %d\n", errno);
971
972 errno = 0xdeadbeef;
973 gmt_tm->tm_mon = 1;
974 gmt_tm->tm_mday = 30;
975 gmt_tm->tm_year = 79;
976 ret = p_asctime(gmt_tm);
977 ok(!ret || broken(!strcmp(ret, "Wed Feb 30 02:58:41 1979\n")), "asctime returned %s\n", ret);
978 ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
979}
980
981static void test__tzset(void)
982{
983 char TZ_env[256];
984 int ret;
985
986 if (sizeof(void*) != sizeof(int))
987 {
988 ok(!p___p__daylight, "___p__daylight() should be 32-bit only\n");
989 ok(!p___p__timezone, "___p__timezone() should be 32-bit only\n");
990 ok(!p___p__dstbias, "___p__dstbias() should be 32-bit only\n");
991 return;
992 }
993
994 if (p__dstbias) {
995 ret = *p__dstbias();
996 ok(ret == -3600, "*__dstbias() = %d\n", ret);
997 ret = *p___p__dstbias();
998 ok(ret == -3600, "*__p__dstbias() = %d\n", ret);
999 }
1000 else
1001 win_skip("__dstbias() is not available.\n");
1002
1003 _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
1004
1005 ret = *p___p__daylight();
1006 ok(ret == 1, "*__p__daylight() = %d\n", ret);
1007 ret = *p___p__timezone();
1008 ok(ret == 28800, "*__p__timezone() = %d\n", ret);
1009 ret = *p___p__dstbias();
1010 ok(ret == -3600, "*__p__dstbias() = %d\n", ret);
1011
1012 _putenv("TZ=xxx+1yyy");
1013 _tzset();
1014 ret = *p___p__daylight();
1015 ok(ret == 121, "*__p__daylight() = %d\n", ret);
1016 ret = *p___p__timezone();
1017 ok(ret == 3600, "*__p__timezone() = %d\n", ret);
1018 ret = *p___p__dstbias();
1019 ok(ret == -3600, "*__p__dstbias() = %d\n", ret);
1020
1021 *p___p__dstbias() = 0;
1022 _putenv("TZ=xxx+1:3:5zzz");
1023 _tzset();
1024 ret = *p___p__daylight();
1025 ok(ret == 122, "*__p__daylight() = %d\n", ret);
1026 ret = *p___p__timezone();
1027 ok(ret == 3785, "*__p__timezone() = %d\n", ret);
1028 ret = *p___p__dstbias();
1029 ok(ret == 0, "*__p__dstbias() = %d\n", ret);
1030
1031 _putenv(TZ_env);
1032}
1033
1035{
1036 init();
1037
1038 test__tzset();
1039 test_strftime();
1040 test_ctime();
1041 test_gmtime();
1042 test_gmtime64();
1043 test_mktime();
1045 test_strdate();
1046 test_strtime();
1047 test_wstrdate();
1048 test_wstrtime();
1051 test_daylight();
1052 test_asctime();
1053}
#define EINVAL
Definition: acclib.h:90
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERANGE
Definition: acclib.h:92
#define EBADF
Definition: acclib.h:82
#define __cdecl
Definition: accygwin.h:79
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:20
_wstrtime
_wstrdate
#define NULL
Definition: types.h:112
#define CP_ACP
Definition: compat.h:109
#define GetProcAddress(x, y)
Definition: compat.h:753
#define WideCharToMultiByte
Definition: compat.h:111
static DOUBLE local_time(DOUBLE time, DateInstance *date)
Definition: date.c:351
static DOUBLE day(DOUBLE time)
Definition: date.c:117
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
Definition: timezone.c:262
static const WCHAR month[12][4]
Definition: session.c:2150
__kernel_time_t time_t
Definition: linux.h:252
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
time_t now
Definition: finger.c:65
BOOLEAN valid
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LC_ALL
Definition: locale.h:17
#define LC_TIME
Definition: locale.h:22
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP int __cdecl putenv(_In_z_ const char *_EnvString)
_Check_return_ _CRTIMP int __cdecl _putenv(_In_z_ const char *_EnvString)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
__u16 ctime
Definition: mkdosfs.c:4
__u16 date
Definition: mkdosfs.c:8
__u16 time
Definition: mkdosfs.c:8
static struct test_info tests[]
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
BOOL todo
Definition: filedlg.c:313
#define SECSPERMIN
Definition: time.c:36
#define todo_wine_if(is_todo)
Definition: custom.c:86
static void test_daylight(void)
Definition: time.c:659
static void test_localtime32_s(void)
Definition: time.c:543
#define SECSPERDAY
Definition: time.c:33
static __time32_t *static __time64_t *static int *__cdecl * p__daylight(void)
static void test_mktime(void)
Definition: time.c:287
static void init(void)
Definition: time.c:74
static void test_strtime(void)
Definition: time.c:480
#define _MAX__TIME64_T
Definition: time.c:31
static void test_localtime(void)
Definition: time.c:398
static void test__tzset(void)
Definition: time.c:981
#define SECSPERHOUR
Definition: time.c:34
static void test_strdate(void)
Definition: time.c:445
static long *__cdecl * p___p__timezone(void)
static void test_localtime64_s(void)
Definition: time.c:594
static void test_gmtime64(void)
Definition: time.c:215
static __time32_t *static struct tm *__cdecl * p_gmtime64(__time64_t *)
static void test_gmtime(void)
Definition: time.c:119
static long *__cdecl * p___p__dstbias(void)
static __time64_t *static size_t
Definition: time.c:60
static struct tm *__cdecl * p_gmtime(time_t *)
static void test_strftime(void)
Definition: time.c:680
static long *__cdecl * p__dstbias(void)
static void test_ctime(void)
Definition: time.c:112
static const char const struct tm *static const char const struct tm void *static const wchar_t const struct tm *static char *__cdecl * p_asctime(const struct tm *)
static int *__cdecl * p___p__daylight(void)
static void test_wstrdate(void)
Definition: time.c:517
static int get_test_year(time_t *start)
Definition: time.c:99
static void test_wstrtime(void)
Definition: time.c:530
static void test_asctime(void)
Definition: time.c:916
static struct tm *__cdecl * p_gmtime32(__time32_t *)
#define L(x)
Definition: ntvdm.h:50
#define err(...)
#define errno
Definition: errno.h:18
_CRTIMP time_t __cdecl mktime(struct tm *_Tm)
Definition: time.h:418
_CRTIMP void __cdecl _tzset(void)
Definition: timezone.c:92
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
long __time32_t
Definition: time.h:24
DWORD LCID
Definition: nls.h:13
#define win_skip
Definition: test.h:164
_strdate
Definition: time.h:297
_strtime
Definition: time.h:313
#define memset(x, y, z)
Definition: compat.h:39
WCHAR StandardName[32]
Definition: winbase.h:1238
const char * time
Definition: time.c:48
const char * date
Definition: time.c:47
const char * pm
Definition: time.c:45
int unk
Definition: time.c:50
LCID lcid
Definition: time.c:49
int refcount
Definition: time.c:51
const char * short_date
Definition: time.c:46
const char * am
Definition: time.c:44
Definition: format.c:58
Definition: send.c:48
Definition: time.h:68
int tm_mon
Definition: time.h:73
int tm_year
Definition: time.h:74
int tm_hour
Definition: time.h:71
int tm_sec
Definition: time.h:69
int tm_isdst
Definition: time.h:77
int tm_yday
Definition: time.h:76
int tm_mday
Definition: time.h:72
int tm_min
Definition: time.h:70
int tm_wday
Definition: time.h:75
#define setlocale(n, s)
Definition: locale.h:46
int errno_t
Definition: corecrt.h:615
__int64 __time64_t
Definition: corecrt.h:619
int ret
#define TIME_ZONE_ID_INVALID
Definition: winbase.h:312
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _snprintf
Definition: xmlstorage.h:200