Add test for correctly interpreting %% printf format string conversion
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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()
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 static void test_mktime()
52 {
53     TIME_ZONE_INFORMATION tzinfo;
54     DWORD res =  GetTimeZoneInformation(&tzinfo);
55     struct tm my_tm, sav_tm;
56     time_t nulltime, local_time;
57     char TZ_env[256];
58     int secs;
59
60     ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
61     /* Bias may be positive or negative, to use offset of one day */
62     secs= SECSPERDAY - (tzinfo.Bias +
63       ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
64       ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN;
65     my_tm.tm_mday = 1 + secs/SECSPERDAY;
66     secs = secs % SECSPERDAY;
67     my_tm.tm_hour = secs / SECSPERHOUR;
68     secs = secs % SECSPERHOUR;
69     my_tm.tm_min = secs / SECSPERMIN;
70     secs = secs % SECSPERMIN;
71     my_tm.tm_sec = secs;
72
73     my_tm.tm_year = 70;
74     my_tm.tm_mon  =  0;
75     my_tm.tm_isdst=  0;
76
77     sav_tm = my_tm;
78   
79     local_time = mktime(&my_tm);
80     ok(((DWORD)local_time == SECSPERDAY), "mktime returned 0x%08lx\n",(DWORD)local_time);
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 0x%08lx\n",(DWORD)local_time);
87     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
88         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
89         my_tm.tm_sec == sav_tm.tm_sec
90             , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
91             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
92             my_tm.tm_hour,my_tm.tm_sec,
93             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
94             sav_tm.tm_hour,sav_tm.tm_sec);
95     my_tm = sav_tm;
96     my_tm.tm_min -= 60;
97     my_tm.tm_hour += 1;
98     local_time = mktime(&my_tm);
99     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
100     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
101         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
102         my_tm.tm_sec == sav_tm.tm_sec
103             , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
104             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
105             my_tm.tm_hour,my_tm.tm_sec,
106             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
107             sav_tm.tm_hour,sav_tm.tm_sec);
108     my_tm = sav_tm;
109     my_tm.tm_mon -= 12;
110     my_tm.tm_year += 1;
111     local_time = mktime(&my_tm);
112     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
113     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
114         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
115         my_tm.tm_sec == sav_tm.tm_sec
116             , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
117             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
118             my_tm.tm_hour,my_tm.tm_sec,
119             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
120             sav_tm.tm_hour,sav_tm.tm_sec);
121     my_tm = sav_tm;
122     my_tm.tm_mon += 12;
123     my_tm.tm_year -= 1;
124     local_time = mktime(&my_tm);
125     ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
126     ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
127         my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
128         my_tm.tm_sec == sav_tm.tm_sec
129             , "mktime returned %3d-%02d-%02d %02d:%02d expected  %3d-%02d-%02d %02d:%02d.\n",
130             my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
131             my_tm.tm_hour,my_tm.tm_sec,
132             sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
133             sav_tm.tm_hour,sav_tm.tm_sec);
134     /* now a bad time example */
135     my_tm = sav_tm;
136     my_tm.tm_year -= 1;
137     local_time = mktime(&my_tm);
138     ok((local_time == -1), "(bad time) mktime returned 0x%08lx\n",(DWORD)local_time);
139
140     my_tm = sav_tm;
141     /* TEST that we are independent from the TZ variable */
142     /*Argh, msvcrt doesn't have setenv() */
143     _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
144     putenv("TZ=GMT");
145     nulltime = mktime(&my_tm);
146     ok(((DWORD)nulltime == SECSPERDAY),"mktime returned 0x%08lx\n",(DWORD)nulltime);
147     putenv(TZ_env);
148 }
149 static void test_localtime()
150 {
151     TIME_ZONE_INFORMATION tzinfo;
152     DWORD res =  GetTimeZoneInformation(&tzinfo);
153     time_t gmt = (time_t)(SECSPERDAY + (tzinfo.Bias +
154       ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
155       ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN);
156
157     char TZ_env[256];
158     struct tm* lt;
159     
160     ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
161     lt = localtime(&gmt);
162     ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
163         (lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
164         (lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst ==
165                                                       (res == TIME_ZONE_ID_DAYLIGHT))),
166        "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
167        lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
168        lt->tm_min, lt->tm_sec, lt->tm_isdst); 
169
170     _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
171     putenv("TZ=GMT");
172     lt = localtime(&gmt);
173     ok(((lt->tm_year == 70) && (lt->tm_mon  == 0) && (lt->tm_yday  == 1) &&
174         (lt->tm_mday ==  2) && (lt->tm_wday == 5) && (lt->tm_hour  == 0) &&
175         (lt->tm_min  ==  0) && (lt->tm_sec  == 0) && (lt->tm_isdst ==
176                                                       (res == TIME_ZONE_ID_DAYLIGHT))),
177        "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
178        lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, 
179        lt->tm_min, lt->tm_sec, lt->tm_isdst); 
180     putenv(TZ_env);
181 }
182
183
184 START_TEST(time)
185 {
186     test_gmtime();
187     test_mktime();
188     test_localtime();
189 }