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