msvcrt: Fixed space in type with double indirection.
[wine] / dlls / msvcrt / tests / time.c
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 "time.h"
24
25 #include <stdlib.h> /*setenv*/
26 #include <stdio.h> /*printf*/
27
28 #define SECSPERDAY         86400
29 #define SECSPERHOUR        3600
30 #define SECSPERMIN         60
31 #define MINSPERHOUR        60
32 #define HOURSPERDAY        24
33
34 static void test_gmtime(void)
35 {
36     time_t gmt = (time_t)NULL;
37     struct tm* gmt_tm = gmtime(&gmt);
38     if(gmt_tm == 0)
39         {
40             ok(0,"gmtime() error\n");
41             return;
42         }
43     ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon  == 0) && (gmt_tm->tm_yday  == 0) &&
44         (gmt_tm->tm_mday ==  1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour  == 0) &&
45         (gmt_tm->tm_min  ==  0) && (gmt_tm->tm_sec  == 0) && (gmt_tm->tm_isdst == 0)),
46        "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
47        gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, 
48        gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); 
49   
50 }
51
52 static void test_mktime(void)
53 {
54     TIME_ZONE_INFORMATION tzinfo;
55     DWORD res =  GetTimeZoneInformation(&tzinfo);
56     struct tm my_tm, sav_tm;
57     time_t nulltime, local_time;
58     char TZ_env[256];
59     int secs;
60
61     ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
62     /* Bias may be positive or negative, to use offset of one day */
63     secs= SECSPERDAY - tzinfo.Bias * SECSPERMIN;
64     my_tm.tm_mday = 1 + secs/SECSPERDAY;
65     secs = secs % SECSPERDAY;
66     my_tm.tm_hour = secs / SECSPERHOUR;
67     secs = secs % SECSPERHOUR;
68     my_tm.tm_min = secs / SECSPERMIN;
69     secs = secs % SECSPERMIN;
70     my_tm.tm_sec = secs;
71
72     my_tm.tm_year = 70;
73     my_tm.tm_mon  =  0;
74     my_tm.tm_isdst=  0;
75
76     sav_tm = my_tm;
77   
78     local_time = mktime(&my_tm);
79     ok(((DWORD)local_time == SECSPERDAY), "mktime returned %u, expected %u\n",
80         (DWORD)local_time, SECSPERDAY);
81     /* now test some unnormalized struct tm's */
82     my_tm = sav_tm;
83     my_tm.tm_sec += 60;
84     my_tm.tm_min -= 1;
85     local_time = mktime(&my_tm);
86     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned %u, expected %u\n",
87         (DWORD)local_time, SECSPERDAY);
88     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
89         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
90         my_tm.tm_sec == sav_tm.tm_sec,
91             "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
92             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
93             my_tm.tm_hour,my_tm.tm_sec,
94             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
95             sav_tm.tm_hour,sav_tm.tm_sec);
96     my_tm = sav_tm;
97     my_tm.tm_min -= 60;
98     my_tm.tm_hour += 1;
99     local_time = mktime(&my_tm);
100     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned %u, expected %u\n",
101         (DWORD)local_time, SECSPERDAY);
102     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
103         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
104         my_tm.tm_sec == sav_tm.tm_sec,
105             "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
106             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
107             my_tm.tm_hour,my_tm.tm_sec,
108             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
109             sav_tm.tm_hour,sav_tm.tm_sec);
110     my_tm = sav_tm;
111     my_tm.tm_mon -= 12;
112     my_tm.tm_year += 1;
113     local_time = mktime(&my_tm);
114     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned %u, expected %u\n",
115         (DWORD)local_time, SECSPERDAY);
116     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
117         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
118         my_tm.tm_sec == sav_tm.tm_sec,
119             "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
120             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
121             my_tm.tm_hour,my_tm.tm_sec,
122             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
123             sav_tm.tm_hour,sav_tm.tm_sec);
124     my_tm = sav_tm;
125     my_tm.tm_mon += 12;
126     my_tm.tm_year -= 1;
127     local_time = mktime(&my_tm);
128     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned %u, expected %u\n",
129         (DWORD)local_time, SECSPERDAY);
130     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
131         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
132         my_tm.tm_sec == sav_tm.tm_sec,
133             "mktime returned %2d-%02d-%02d %02d:%02d expected %2d-%02d-%02d %02d:%02d\n",
134             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
135             my_tm.tm_hour,my_tm.tm_sec,
136             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
137             sav_tm.tm_hour,sav_tm.tm_sec);
138     /* now a bad time example */
139     my_tm = sav_tm;
140     my_tm.tm_year -= 1;
141     local_time = mktime(&my_tm);
142     ok((local_time == -1), "(bad time) mktime returned %d, expected -1\n", (int)local_time);
143
144     my_tm = sav_tm;
145     /* TEST that we are independent from the TZ variable */
146     /*Argh, msvcrt doesn't have setenv() */
147     _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
148     putenv("TZ=GMT");
149     nulltime = mktime(&my_tm);
150     ok(((DWORD)nulltime == SECSPERDAY),"mktime returned 0x%08x\n",(DWORD)nulltime);
151     putenv(TZ_env);
152 }
153
154 static void test_localtime(void)
155 {
156     TIME_ZONE_INFORMATION tzinfo;
157     DWORD res =  GetTimeZoneInformation(&tzinfo);
158     time_t gmt = (time_t)(SECSPERDAY + tzinfo.Bias * SECSPERMIN);
159
160     char TZ_env[256];
161     struct tm* lt;
162     
163     ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
164     lt = localtime(&gmt);
165     ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
166         (lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
167         (lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst == 0)),
168        "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
169        lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
170        lt->tm_min, lt->tm_sec, lt->tm_isdst); 
171
172     _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
173     putenv("TZ=GMT");
174     lt = localtime(&gmt);
175     ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
176         (lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
177         (lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst == 0)),
178        "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
179        lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
180        lt->tm_min, lt->tm_sec, lt->tm_isdst); 
181     putenv(TZ_env);
182
183     /* June 22 */
184     gmt += 201 * SECSPERDAY;
185     lt = localtime(&gmt);
186     gmt += (lt->tm_isdst ? tzinfo.DaylightBias : tzinfo.StandardBias) * SECSPERMIN;
187     lt = localtime(&gmt);
188     ok(((lt->tm_year == 70) && (lt->tm_mon  == 6) && (lt->tm_yday  == 202) &&
189         (lt->tm_mday == 22) && (lt->tm_wday == 3) && (lt->tm_hour  == 0) &&
190         (lt->tm_min  ==  0) && (lt->tm_sec  == 0)),
191        "Wrong date:Year %d mon %d yday %d mday %d wday %d hour %d min %d sec %d dst %d\n",
192        lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
193        lt->tm_min, lt->tm_sec, lt->tm_isdst); 
194 }
195
196 static void test_strdate(void)
197 {
198     char date[16], * result;
199     int month, day, year, count, len;
200
201     result = _strdate(date);
202     ok(result == date, "Wrong return value\n");
203     len = strlen(date);
204     ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
205     count = sscanf(date, "%02d/%02d/%02d", &month, &day, &year);
206     ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
207 }
208
209 static void test_strtime(void)
210 {
211     char time[16], * result;
212     int hour, minute, second, count, len;
213
214     result = _strtime(time);
215     ok(result == time, "Wrong return value\n");
216     len = strlen(time);
217     ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
218     count = sscanf(time, "%02d:%02d:%02d", &hour, &minute, &second);
219     ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
220 }
221
222 static void test_wstrdate(void)
223 {
224     wchar_t date[16], * result;
225     int month, day, year, count, len;
226     wchar_t format[] = { '%','0','2','d','/','%','0','2','d','/','%','0','2','d',0 };
227
228     result = _wstrdate(date);
229     ok(result == date, "Wrong return value\n");
230     len = wcslen(date);
231     ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
232     count = swscanf(date, format, &month, &day, &year);
233     ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
234 }
235
236 static void test_wstrtime(void)
237 {
238     wchar_t time[16], * result;
239     int hour, minute, second, count, len;
240     wchar_t format[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d',0 };
241
242     result = _wstrtime(time);
243     ok(result == time, "Wrong return value\n");
244     len = wcslen(time);
245     ok(len == 8, "Wrong length: returned %d, should be 8\n", len);
246     count = swscanf(time, format, &hour, &minute, &second);
247     ok(count == 3, "Wrong format: count = %d, should be 3\n", count);
248 }
249
250 START_TEST(time)
251 {
252     test_gmtime();
253     test_mktime();
254     test_localtime();
255     test_strdate();
256     test_strtime();
257     test_wstrdate();
258     test_wstrtime();
259 }