1 /* 2 * Unit test suite for time functions 3 * 4 * Copyright 2004 Uwe Bonnes 5 * Copyright 2007 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "precomp.h" 23 24 static BOOL (WINAPI *pTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); 25 static BOOL (WINAPI *pSystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); 26 static BOOL (WINAPI *pGetSystemTimes)(LPFILETIME, LPFILETIME, LPFILETIME); 27 static int (WINAPI *pGetCalendarInfoA)(LCID,CALID,CALTYPE,LPSTR,int,LPDWORD); 28 static int (WINAPI *pGetCalendarInfoW)(LCID,CALID,CALTYPE,LPWSTR,int,LPDWORD); 29 static DWORD (WINAPI *pGetDynamicTimeZoneInformation)(DYNAMIC_TIME_ZONE_INFORMATION*); 30 static void (WINAPI *pGetSystemTimePreciseAsFileTime)(LPFILETIME); 31 static BOOL (WINAPI *pGetTimeZoneInformationForYear)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION); 32 33 #define SECSPERMIN 60 34 #define SECSPERDAY 86400 35 /* 1601 to 1970 is 369 years plus 89 leap days */ 36 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) 37 #define TICKSPERSEC 10000000 38 #define TICKSPERMSEC 10000 39 #define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) 40 41 42 #define NEWYEAR_1980_HI 0x01a8e79f 43 #define NEWYEAR_1980_LO 0xe1d58000 44 45 #define MAYDAY_2002_HI 0x01c1f107 46 #define MAYDAY_2002_LO 0xb82b6000 47 48 #define ATIME_HI 0x1c2349b 49 #define ATIME_LOW 0x580716b0 50 51 #define LOCAL_ATIME_HI 0x01c23471 52 #define LOCAL_ATIME_LOW 0x6f310eb0 53 54 #define DOS_DATE(y,m,d) ( (((y)-1980)<<9) | ((m)<<5) | (d) ) 55 #define DOS_TIME(h,m,s) ( ((h)<<11) | ((m)<<5) | ((s)>>1) ) 56 57 58 #define SETUP_1980(st) \ 59 (st).wYear = 1980; \ 60 (st).wMonth = 1; \ 61 (st).wDay = 1; \ 62 (st).wHour = 0; \ 63 (st).wMinute = 0; \ 64 (st).wSecond = 0; \ 65 (st).wMilliseconds = 0; 66 67 #define SETUP_2002(st) \ 68 (st).wYear = 2002; \ 69 (st).wMonth = 5; \ 70 (st).wDay = 1; \ 71 (st).wHour = 12; \ 72 (st).wMinute = 0; \ 73 (st).wSecond = 0; \ 74 (st).wMilliseconds = 0; 75 76 #define SETUP_ATIME(st) \ 77 (st).wYear = 2002; \ 78 (st).wMonth = 7; \ 79 (st).wDay = 26; \ 80 (st).wHour = 11; \ 81 (st).wMinute = 55; \ 82 (st).wSecond = 32; \ 83 (st).wMilliseconds = 123; 84 85 #define SETUP_ZEROTIME(st) \ 86 (st).wYear = 1601; \ 87 (st).wMonth = 1; \ 88 (st).wDay = 1; \ 89 (st).wHour = 0; \ 90 (st).wMinute = 0; \ 91 (st).wSecond = 0; \ 92 (st).wMilliseconds = 0; 93 94 #define SETUP_EARLY(st) \ 95 (st).wYear = 1600; \ 96 (st).wMonth = 12; \ 97 (st).wDay = 31; \ 98 (st).wHour = 23; \ 99 (st).wMinute = 59; \ 100 (st).wSecond = 59; \ 101 (st).wMilliseconds = 999; 102 103 104 static void test_conversions(void) 105 { 106 FILETIME ft; 107 SYSTEMTIME st; 108 109 memset(&ft,0,sizeof ft); 110 111 SetLastError(0xdeadbeef); 112 SETUP_EARLY(st) 113 ok (!SystemTimeToFileTime(&st, &ft), "Conversion succeeded EARLY\n"); 114 ok (GetLastError() == ERROR_INVALID_PARAMETER || 115 GetLastError() == 0xdeadbeef, /* win9x */ 116 "EARLY should be INVALID\n"); 117 118 SETUP_ZEROTIME(st) 119 ok (SystemTimeToFileTime(&st, &ft), "Conversion failed ZERO_TIME\n"); 120 ok( (!((ft.dwHighDateTime != 0) || (ft.dwLowDateTime != 0))), 121 "Wrong time for ATIME: %08x %08x (correct %08x %08x)\n", 122 ft.dwLowDateTime, ft.dwHighDateTime, 0, 0); 123 124 125 SETUP_ATIME(st) 126 ok (SystemTimeToFileTime(&st,&ft), "Conversion Failed ATIME\n"); 127 ok( (!((ft.dwHighDateTime != ATIME_HI) || (ft.dwLowDateTime!=ATIME_LOW))), 128 "Wrong time for ATIME: %08x %08x (correct %08x %08x)\n", 129 ft.dwLowDateTime, ft.dwHighDateTime, ATIME_LOW, ATIME_HI); 130 131 132 SETUP_2002(st) 133 ok (SystemTimeToFileTime(&st, &ft), "Conversion failed 2002\n"); 134 135 ok( (!((ft.dwHighDateTime != MAYDAY_2002_HI) || 136 (ft.dwLowDateTime!=MAYDAY_2002_LO))), 137 "Wrong time for 2002 %08x %08x (correct %08x %08x)\n", ft.dwLowDateTime, 138 ft.dwHighDateTime, MAYDAY_2002_LO, MAYDAY_2002_HI); 139 140 141 SETUP_1980(st) 142 ok((SystemTimeToFileTime(&st, &ft)), "Conversion failed 1980\n"); 143 144 ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) || 145 (ft.dwLowDateTime!=NEWYEAR_1980_LO))) , 146 "Wrong time for 1980 %08x %08x (correct %08x %08x)\n", ft.dwLowDateTime, 147 ft.dwHighDateTime, NEWYEAR_1980_LO,NEWYEAR_1980_HI ); 148 149 ok(DosDateTimeToFileTime(DOS_DATE(1980,1,1),DOS_TIME(0,0,0),&ft), 150 "DosDateTimeToFileTime() failed\n"); 151 152 ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) || 153 (ft.dwLowDateTime!=NEWYEAR_1980_LO))), 154 "Wrong time DosDateTimeToFileTime %08x %08x (correct %08x %08x)\n", 155 ft.dwHighDateTime, ft.dwLowDateTime, NEWYEAR_1980_HI, NEWYEAR_1980_LO); 156 157 } 158 159 static void test_invalid_arg(void) 160 { 161 FILETIME ft; 162 SYSTEMTIME st; 163 164 165 /* Invalid argument checks */ 166 167 memset(&ft,0,sizeof ft); 168 ok( DosDateTimeToFileTime(DOS_DATE(1980,1,1),DOS_TIME(0,0,0),&ft), /* this is 1 Jan 1980 00:00:00 */ 169 "DosDateTimeToFileTime() failed\n"); 170 171 ok( (ft.dwHighDateTime==NEWYEAR_1980_HI) && (ft.dwLowDateTime==NEWYEAR_1980_LO), 172 "filetime for 1/1/80 00:00:00 was %08x %08x\n", ft.dwHighDateTime, ft.dwLowDateTime); 173 174 /* now check SystemTimeToFileTime */ 175 memset(&ft,0,sizeof ft); 176 177 178 /* try with a bad month */ 179 SETUP_1980(st) 180 st.wMonth = 0; 181 182 ok( !SystemTimeToFileTime(&st, &ft), "bad month\n"); 183 184 /* with a bad hour */ 185 SETUP_1980(st) 186 st.wHour = 24; 187 188 ok( !SystemTimeToFileTime(&st, &ft), "bad hour\n"); 189 190 /* with a bad minute */ 191 SETUP_1980(st) 192 st.wMinute = 60; 193 194 ok( !SystemTimeToFileTime(&st, &ft), "bad minute\n"); 195 } 196 197 static LONGLONG system_time_to_minutes(const SYSTEMTIME *st) 198 { 199 BOOL ret; 200 FILETIME ft; 201 LONGLONG minutes; 202 203 SetLastError(0xdeadbeef); 204 ret = SystemTimeToFileTime(st, &ft); 205 ok(ret, "SystemTimeToFileTime error %u\n", GetLastError()); 206 207 minutes = ((LONGLONG)ft.dwHighDateTime << 32) + ft.dwLowDateTime; 208 minutes /= (LONGLONG)600000000; /* convert to minutes */ 209 return minutes; 210 } 211 212 static LONG get_tz_bias(const TIME_ZONE_INFORMATION *tzinfo, DWORD tz_id) 213 { 214 switch (tz_id) 215 { 216 case TIME_ZONE_ID_DAYLIGHT: 217 if (memcmp(&tzinfo->StandardDate, &tzinfo->DaylightDate, sizeof(tzinfo->DaylightDate)) != 0) 218 return tzinfo->DaylightBias; 219 /* fall through */ 220 221 case TIME_ZONE_ID_STANDARD: 222 return tzinfo->StandardBias; 223 224 default: 225 trace("unknown time zone id %d\n", tz_id); 226 /* fall through */ 227 case TIME_ZONE_ID_UNKNOWN: 228 return 0; 229 } 230 } 231 232 static void test_GetTimeZoneInformation(void) 233 { 234 char std_name[32], dlt_name[32]; 235 TIME_ZONE_INFORMATION tzinfo, tzinfo1; 236 BOOL res; 237 DWORD tz_id; 238 SYSTEMTIME st, current, utc, local; 239 FILETIME l_ft, s_ft; 240 LONGLONG l_time, s_time; 241 LONG diff; 242 243 GetSystemTime(&st); 244 s_time = system_time_to_minutes(&st); 245 246 SetLastError(0xdeadbeef); 247 res = SystemTimeToFileTime(&st, &s_ft); 248 ok(res, "SystemTimeToFileTime error %u\n", GetLastError()); 249 SetLastError(0xdeadbeef); 250 res = FileTimeToLocalFileTime(&s_ft, &l_ft); 251 ok(res, "FileTimeToLocalFileTime error %u\n", GetLastError()); 252 SetLastError(0xdeadbeef); 253 res = FileTimeToSystemTime(&l_ft, &local); 254 ok(res, "FileTimeToSystemTime error %u\n", GetLastError()); 255 l_time = system_time_to_minutes(&local); 256 257 tz_id = GetTimeZoneInformation(&tzinfo); 258 ok(tz_id != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 259 260 trace("tz_id %u (%s)\n", tz_id, 261 tz_id == TIME_ZONE_ID_DAYLIGHT ? "TIME_ZONE_ID_DAYLIGHT" : 262 (tz_id == TIME_ZONE_ID_STANDARD ? "TIME_ZONE_ID_STANDARD" : 263 (tz_id == TIME_ZONE_ID_UNKNOWN ? "TIME_ZONE_ID_UNKNOWN" : 264 "TIME_ZONE_ID_INVALID"))); 265 266 WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1, std_name, sizeof(std_name), NULL, NULL); 267 WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1, dlt_name, sizeof(dlt_name), NULL, NULL); 268 trace("bias %d, %s - %s\n", tzinfo.Bias, std_name, dlt_name); 269 trace("standard (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n", 270 tzinfo.StandardDate.wDay, tzinfo.StandardDate.wMonth, 271 tzinfo.StandardDate.wYear, tzinfo.StandardDate.wDayOfWeek, 272 tzinfo.StandardDate.wHour, tzinfo.StandardDate.wMinute, 273 tzinfo.StandardDate.wSecond, tzinfo.StandardDate.wMilliseconds, 274 tzinfo.StandardBias); 275 trace("daylight (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n", 276 tzinfo.DaylightDate.wDay, tzinfo.DaylightDate.wMonth, 277 tzinfo.DaylightDate.wYear, tzinfo.DaylightDate.wDayOfWeek, 278 tzinfo.DaylightDate.wHour, tzinfo.DaylightDate.wMinute, 279 tzinfo.DaylightDate.wSecond, tzinfo.DaylightDate.wMilliseconds, 280 tzinfo.DaylightBias); 281 282 diff = (LONG)(s_time - l_time); 283 ok(diff == tzinfo.Bias + get_tz_bias(&tzinfo, tz_id), 284 "system/local diff %d != tz bias %d\n", 285 diff, tzinfo.Bias + get_tz_bias(&tzinfo, tz_id)); 286 287 ok(SetEnvironmentVariableA("TZ","GMT0") != 0, 288 "SetEnvironmentVariableA failed\n"); 289 res = GetTimeZoneInformation(&tzinfo1); 290 ok(res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 291 292 ok(((tzinfo.Bias == tzinfo1.Bias) && 293 (tzinfo.StandardBias == tzinfo1.StandardBias) && 294 (tzinfo.DaylightBias == tzinfo1.DaylightBias)), 295 "Bias influenced by TZ variable\n"); 296 ok(SetEnvironmentVariableA("TZ",NULL) != 0, 297 "SetEnvironmentVariableA failed\n"); 298 299 if (!pSystemTimeToTzSpecificLocalTime) 300 { 301 win_skip("SystemTimeToTzSpecificLocalTime not available\n"); 302 return; 303 } 304 305 diff = get_tz_bias(&tzinfo, tz_id); 306 307 utc = st; 308 SetLastError(0xdeadbeef); 309 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, ¤t); 310 if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 311 { 312 win_skip("SystemTimeToTzSpecificLocalTime is not implemented\n"); 313 return; 314 } 315 316 ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError()); 317 s_time = system_time_to_minutes(¤t); 318 319 tzinfo.StandardBias -= 123; 320 tzinfo.DaylightBias += 456; 321 322 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 323 ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError()); 324 l_time = system_time_to_minutes(&local); 325 ok(l_time - s_time == diff - get_tz_bias(&tzinfo, tz_id), "got %d, expected %d\n", 326 (LONG)(l_time - s_time), diff - get_tz_bias(&tzinfo, tz_id)); 327 328 /* pretend that there is no transition dates */ 329 tzinfo.DaylightDate.wDay = 0; 330 tzinfo.DaylightDate.wMonth = 0; 331 tzinfo.DaylightDate.wYear = 0; 332 tzinfo.StandardDate.wDay = 0; 333 tzinfo.StandardDate.wMonth = 0; 334 tzinfo.StandardDate.wYear = 0; 335 336 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 337 ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError()); 338 l_time = system_time_to_minutes(&local); 339 ok(l_time - s_time == diff, "got %d, expected %d\n", 340 (LONG)(l_time - s_time), diff); 341 342 /* test 23:01, 31st of December date */ 343 memset(&tzinfo, 0, sizeof(tzinfo)); 344 tzinfo.StandardDate.wMonth = 10; 345 tzinfo.StandardDate.wDay = 5; 346 tzinfo.StandardDate.wHour = 2; 347 tzinfo.StandardDate.wMinute = 0; 348 tzinfo.DaylightDate.wMonth = 4; 349 tzinfo.DaylightDate.wDay = 1; 350 tzinfo.DaylightDate.wHour = 2; 351 tzinfo.Bias = 0; 352 tzinfo.StandardBias = 0; 353 tzinfo.DaylightBias = -60; 354 utc.wYear = 2012; 355 utc.wMonth = 12; 356 utc.wDay = 31; 357 utc.wHour = 23; 358 utc.wMinute = 1; 359 res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local); 360 ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError()); 361 ok(local.wYear==2012 && local.wMonth==12 && local.wDay==31 && local.wHour==23 && local.wMinute==1, 362 "got (%d-%d-%d %02d:%02d), expected (2012-12-31 23:01)\n", 363 local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute); 364 } 365 366 static void test_FileTimeToSystemTime(void) 367 { 368 FILETIME ft; 369 SYSTEMTIME st; 370 ULONGLONG time = (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; 371 BOOL ret; 372 373 ft.dwHighDateTime = 0; 374 ft.dwLowDateTime = 0; 375 ret = FileTimeToSystemTime(&ft, &st); 376 ok( ret, 377 "FileTimeToSystemTime() failed with Error %d\n",GetLastError()); 378 ok(((st.wYear == 1601) && (st.wMonth == 1) && (st.wDay == 1) && 379 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 0) && 380 (st.wMilliseconds == 0)), 381 "Got Year %4d Month %2d Day %2d\n", st.wYear, st.wMonth, st.wDay); 382 383 ft.dwHighDateTime = (UINT)(time >> 32); 384 ft.dwLowDateTime = (UINT)time; 385 ret = FileTimeToSystemTime(&ft, &st); 386 ok( ret, 387 "FileTimeToSystemTime() failed with Error %d\n",GetLastError()); 388 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 389 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 390 (st.wMilliseconds == 0)), 391 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 392 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 393 st.wMilliseconds); 394 } 395 396 static void test_FileTimeToLocalFileTime(void) 397 { 398 FILETIME ft, lft; 399 SYSTEMTIME st; 400 TIME_ZONE_INFORMATION tzinfo; 401 DWORD res = GetTimeZoneInformation(&tzinfo); 402 ULONGLONG time = (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970 + 403 (LONGLONG)(tzinfo.Bias + 404 ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias : 405 ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * 406 SECSPERMIN *TICKSPERSEC; 407 BOOL ret; 408 409 ok( res != TIME_ZONE_ID_INVALID , "GetTimeZoneInformation failed\n"); 410 ft.dwHighDateTime = (UINT)(time >> 32); 411 ft.dwLowDateTime = (UINT)time; 412 ret = FileTimeToLocalFileTime(&ft, &lft); 413 ok( ret, 414 "FileTimeToLocalFileTime() failed with Error %d\n",GetLastError()); 415 FileTimeToSystemTime(&lft, &st); 416 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 417 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 418 (st.wMilliseconds == 0)), 419 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 420 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 421 st.wMilliseconds); 422 423 ok(SetEnvironmentVariableA("TZ","GMT") != 0, 424 "SetEnvironmentVariableA failed\n"); 425 ok(res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n"); 426 ret = FileTimeToLocalFileTime(&ft, &lft); 427 ok( ret, 428 "FileTimeToLocalFileTime() failed with Error %d\n",GetLastError()); 429 FileTimeToSystemTime(&lft, &st); 430 ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) && 431 (st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) && 432 (st.wMilliseconds == 0)), 433 "Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n", 434 st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, 435 st.wMilliseconds); 436 ok(SetEnvironmentVariableA("TZ",NULL) != 0, 437 "SetEnvironmentVariableA failed\n"); 438 } 439 440 typedef struct { 441 int nr; /* test case number for easier lookup */ 442 TIME_ZONE_INFORMATION *ptz; /* ptr to timezone */ 443 SYSTEMTIME slt; /* system/local time to convert */ 444 WORD ehour; /* expected hour */ 445 } TZLT2ST_case; 446 447 static void test_TzSpecificLocalTimeToSystemTime(void) 448 { 449 TIME_ZONE_INFORMATION tzE, tzW, tzS; 450 SYSTEMTIME result; 451 int i, j, year; 452 453 if (!pTzSpecificLocalTimeToSystemTime || !pSystemTimeToTzSpecificLocalTime) 454 { 455 win_skip("TzSpecificLocalTimeToSystemTime or SystemTimeToTzSpecificLocalTime not available\n"); 456 return; 457 } 458 459 ZeroMemory( &tzE, sizeof(tzE)); 460 ZeroMemory( &tzW, sizeof(tzW)); 461 ZeroMemory( &tzS, sizeof(tzS)); 462 /* timezone Eastern hemisphere */ 463 tzE.Bias=-600; 464 tzE.StandardBias=0; 465 tzE.DaylightBias=-60; 466 tzE.StandardDate.wMonth=10; 467 tzE.StandardDate.wDayOfWeek=0; /* Sunday */ 468 tzE.StandardDate.wDay=5; /* last (Sunday) of the month */ 469 tzE.StandardDate.wHour=3; 470 tzE.DaylightDate.wMonth=3; 471 tzE.DaylightDate.wDay=5; 472 tzE.DaylightDate.wHour=2; 473 /* timezone Western hemisphere */ 474 tzW.Bias=240; 475 tzW.StandardBias=0; 476 tzW.DaylightBias=-60; 477 tzW.StandardDate.wMonth=10; 478 tzW.StandardDate.wDayOfWeek=0; /* Sunday */ 479 tzW.StandardDate.wDay=4; /* 4th (Sunday) of the month */ 480 tzW.StandardDate.wHour=2; 481 tzW.DaylightDate.wMonth=4; 482 tzW.DaylightDate.wDay=1; 483 tzW.DaylightDate.wHour=2; 484 /* timezone Southern hemisphere */ 485 tzS.Bias=240; 486 tzS.StandardBias=0; 487 tzS.DaylightBias=-60; 488 tzS.StandardDate.wMonth=4; 489 tzS.StandardDate.wDayOfWeek=0; /*Sunday */ 490 tzS.StandardDate.wDay=1; /* 1st (Sunday) of the month */ 491 tzS.StandardDate.wHour=2; 492 tzS.DaylightDate.wMonth=10; 493 tzS.DaylightDate.wDay=4; 494 tzS.DaylightDate.wHour=2; 495 /*tests*/ 496 /* TzSpecificLocalTimeToSystemTime */ 497 { TZLT2ST_case cases[] = { 498 /* standard->daylight transition */ 499 { 1, &tzE, {2004,3,-1,28,1,0,0,0}, 15 }, 500 { 2, &tzE, {2004,3,-1,28,1,59,59,999}, 15}, 501 { 3, &tzE, {2004,3,-1,28,2,0,0,0}, 15}, 502 /* daylight->standard transition */ 503 { 4, &tzE, {2004,10,-1,31,2,0,0,0} , 15 }, 504 { 5, &tzE, {2004,10,-1,31,2,59,59,999}, 15 }, 505 { 6, &tzE, {2004,10,-1,31,3,0,0,0}, 17 }, 506 /* West and with fixed weekday of the month */ 507 { 7, &tzW, {2004,4,-1,4,1,0,0,0}, 5}, 508 { 8, &tzW, {2004,4,-1,4,1,59,59,999}, 5}, 509 { 9, &tzW, {2004,4,-1,4,2,0,0,0}, 5}, 510 { 10, &tzW, {2004,10,-1,24,1,0,0,0}, 4}, 511 { 11, &tzW, {2004,10,-1,24,1,59,59,999}, 4}, 512 { 12, &tzW, {2004,10,-1,24,2,0,0,0 }, 6}, 513 /* and now South */ 514 { 13, &tzS, {2004,4,-1,4,1,0,0,0}, 4}, 515 { 14, &tzS, {2004,4,-1,4,1,59,59,999}, 4}, 516 { 15, &tzS, {2004,4,-1,4,2,0,0,0}, 6}, 517 { 16, &tzS, {2004,10,-1,24,1,0,0,0}, 5}, 518 { 17, &tzS, {2004,10,-1,24,1,59,59,999}, 5}, 519 { 18, &tzS, {2004,10,-1,24,2,0,0,0}, 5}, 520 {0} 521 }; 522 /* days of transitions to put into the cases array */ 523 int yeardays[][6]= 524 { 525 {28,31,4,24,4,24} /* 1999 */ 526 , {26,29,2,22,2,22} /* 2000 */ 527 , {25,28,1,28,1,28} /* 2001 */ 528 , {31,27,7,27,7,27} /* 2002 */ 529 , {30,26,6,26,6,26} /* 2003 */ 530 , {28,31,4,24,4,24} /* 2004 */ 531 , {27,30,3,23,3,23} /* 2005 */ 532 , {26,29,2,22,2,22} /* 2006 */ 533 , {25,28,1,28,1,28} /* 2007 */ 534 , {30,26,6,26,6,26} /* 2008 */ 535 , {29,25,5,25,5,25} /* 2009 */ 536 , {28,31,4,24,4,24} /* 2010 */ 537 , {27,30,3,23,3,23} /* 2011 */ 538 , {25,28,1,28,1,28} /* 2012 */ 539 , {31,27,7,27,7,27} /* 2013 */ 540 , {30,26,6,26,6,26} /* 2014 */ 541 , {29,25,5,25,5,25} /* 2015 */ 542 , {27,30,3,23,3,23} /* 2016 */ 543 , {26,29,2,22,2,22} /* 2017 */ 544 , {25,28,1,28,1,28} /* 2018 */ 545 , {31,27,7,27,7,27} /* 2019 */ 546 ,{0} 547 }; 548 for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) { 549 for (i=0; cases[i].nr; i++) { 550 if(i) cases[i].nr += 18; 551 cases[i].slt.wYear = year; 552 cases[i].slt.wDay = yeardays[j][i/3]; 553 pTzSpecificLocalTimeToSystemTime( cases[i].ptz, &(cases[i].slt), &result); 554 ok( result.wHour == cases[i].ehour, 555 "Test TzSpecificLocalTimeToSystemTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n", 556 cases[i].nr, result.wYear, result.wMonth, result.wDay, 557 result.wHour, result.wMinute, cases[i].ehour); 558 } 559 } 560 } 561 /* SystemTimeToTzSpecificLocalTime */ 562 { TZLT2ST_case cases[] = { 563 /* standard->daylight transition */ 564 { 1, &tzE, {2004,3,-1,27,15,0,0,0}, 1 }, 565 { 2, &tzE, {2004,3,-1,27,15,59,59,999}, 1}, 566 { 3, &tzE, {2004,3,-1,27,16,0,0,0}, 3}, 567 /* daylight->standard transition */ 568 { 4, &tzE, {2004,10,-1,30,15,0,0,0}, 2 }, 569 { 5, &tzE, {2004,10,-1,30,15,59,59,999}, 2 }, 570 { 6, &tzE, {2004,10,-1,30,16,0,0,0}, 2 }, 571 /* West and with fixed weekday of the month */ 572 { 7, &tzW, {2004,4,-1,4,5,0,0,0}, 1}, 573 { 8, &tzW, {2004,4,-1,4,5,59,59,999}, 1}, 574 { 9, &tzW, {2004,4,-1,4,6,0,0,0}, 3}, 575 { 10, &tzW, {2004,10,-1,24,4,0,0,0}, 1}, 576 { 11, &tzW, {2004,10,-1,24,4,59,59,999}, 1}, 577 { 12, &tzW, {2004,10,-1,24,5,0,0,0 }, 1}, 578 /* and now South */ 579 { 13, &tzS, {2004,4,-1,4,4,0,0,0}, 1}, 580 { 14, &tzS, {2004,4,-1,4,4,59,59,999}, 1}, 581 { 15, &tzS, {2004,4,-1,4,5,0,0,0}, 1}, 582 { 16, &tzS, {2004,10,-1,24,5,0,0,0}, 1}, 583 { 17, &tzS, {2004,10,-1,24,5,59,59,999}, 1}, 584 { 18, &tzS, {2004,10,-1,24,6,0,0,0}, 3}, 585 586 {0} 587 }; 588 /* days of transitions to put into the cases array */ 589 int yeardays[][6]= 590 { 591 {27,30,4,24,4,24} /* 1999 */ 592 , {25,28,2,22,2,22} /* 2000 */ 593 , {24,27,1,28,1,28} /* 2001 */ 594 , {30,26,7,27,7,27} /* 2002 */ 595 , {29,25,6,26,6,26} /* 2003 */ 596 , {27,30,4,24,4,24} /* 2004 */ 597 , {26,29,3,23,3,23} /* 2005 */ 598 , {25,28,2,22,2,22} /* 2006 */ 599 , {24,27,1,28,1,28} /* 2007 */ 600 , {29,25,6,26,6,26} /* 2008 */ 601 , {28,24,5,25,5,25} /* 2009 */ 602 , {27,30,4,24,4,24} /* 2010 */ 603 , {26,29,3,23,3,23} /* 2011 */ 604 , {24,27,1,28,1,28} /* 2012 */ 605 , {30,26,7,27,7,27} /* 2013 */ 606 , {29,25,6,26,6,26} /* 2014 */ 607 , {28,24,5,25,5,25} /* 2015 */ 608 , {26,29,3,23,3,23} /* 2016 */ 609 , {25,28,2,22,2,22} /* 2017 */ 610 , {24,27,1,28,1,28} /* 2018 */ 611 , {30,26,7,27,7,27} /* 2019 */ 612 , {0} 613 }; 614 for( j=0 , year = 1999; yeardays[j][0] ; j++, year++) { 615 for (i=0; cases[i].nr; i++) { 616 if(i) cases[i].nr += 18; 617 cases[i].slt.wYear = year; 618 cases[i].slt.wDay = yeardays[j][i/3]; 619 pSystemTimeToTzSpecificLocalTime( cases[i].ptz, &(cases[i].slt), &result); 620 ok( result.wHour == cases[i].ehour, 621 "Test SystemTimeToTzSpecificLocalTime #%d. Got %4d-%02d-%02d %02d:%02d. Expect hour = %02d\n", 622 cases[i].nr, result.wYear, result.wMonth, result.wDay, 623 result.wHour, result.wMinute, cases[i].ehour); 624 } 625 } 626 627 } 628 } 629 630 static void test_FileTimeToDosDateTime(void) 631 { 632 FILETIME ft = { 0 }; 633 WORD fatdate, fattime; 634 BOOL ret; 635 636 if (0) 637 { 638 /* Crashes */ 639 FileTimeToDosDateTime(NULL, NULL, NULL); 640 } 641 /* Parameter checking */ 642 SetLastError(0xdeadbeef); 643 ret = FileTimeToDosDateTime(&ft, NULL, NULL); 644 ok(!ret, "expected failure\n"); 645 ok(GetLastError() == ERROR_INVALID_PARAMETER, 646 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 647 648 SetLastError(0xdeadbeef); 649 ret = FileTimeToDosDateTime(&ft, &fatdate, NULL); 650 ok(!ret, "expected failure\n"); 651 ok(GetLastError() == ERROR_INVALID_PARAMETER, 652 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 653 654 SetLastError(0xdeadbeef); 655 ret = FileTimeToDosDateTime(&ft, NULL, &fattime); 656 ok(!ret, "expected failure\n"); 657 ok(GetLastError() == ERROR_INVALID_PARAMETER, 658 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 659 660 SetLastError(0xdeadbeef); 661 ret = FileTimeToDosDateTime(&ft, &fatdate, &fattime); 662 ok(!ret, "expected failure\n"); 663 ok(GetLastError() == ERROR_INVALID_PARAMETER, 664 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 665 } 666 667 static void test_GetCalendarInfo(void) 668 { 669 char bufferA[20]; 670 WCHAR bufferW[20]; 671 DWORD val1, val2; 672 int ret, ret2; 673 674 if (!pGetCalendarInfoA || !pGetCalendarInfoW) 675 { 676 trace( "GetCalendarInfo missing\n" ); 677 return; 678 } 679 680 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 681 NULL, 0, &val1 ); 682 ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() ); 683 ok( ret == sizeof(val1), "wrong size %u\n", ret ); 684 ok( val1 >= 2000 && val1 < 2100, "wrong value %u\n", val1 ); 685 686 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 687 NULL, 0, &val2 ); 688 ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() ); 689 ok( ret == sizeof(val2)/sizeof(WCHAR), "wrong size %u\n", ret ); 690 ok( val1 == val2, "A/W mismatch %u/%u\n", val1, val2 ); 691 692 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferA, sizeof(bufferA), NULL ); 693 ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() ); 694 ok( ret == 5, "wrong size %u\n", ret ); 695 ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 ); 696 697 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, sizeof(bufferW), NULL ); 698 ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() ); 699 ok( ret == 5, "wrong size %u\n", ret ); 700 memset( bufferA, 0x55, sizeof(bufferA) ); 701 WideCharToMultiByte( CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL ); 702 ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 ); 703 704 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 705 NULL, 0, NULL ); 706 ok( !ret, "GetCalendarInfoA succeeded\n" ); 707 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 708 709 ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL ); 710 ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() ); 711 ok( ret == 5, "wrong size %u\n", ret ); 712 713 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, 714 NULL, 0, NULL ); 715 ok( !ret, "GetCalendarInfoW succeeded\n" ); 716 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 717 718 ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL ); 719 ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() ); 720 ok( ret == 5, "wrong size %u\n", ret ); 721 722 ret = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 723 bufferA, sizeof(bufferA), NULL); 724 ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() ); 725 ret2 = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 726 bufferA, 0, NULL); 727 ok( ret2, "GetCalendarInfoA failed err %u\n", GetLastError() ); 728 ok( ret == ret2, "got %d, expected %d\n", ret2, ret ); 729 730 ret2 = pGetCalendarInfoW( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1, 731 bufferW, sizeof(bufferW), NULL); 732 ok( ret2, "GetCalendarInfoW failed err %u\n", GetLastError() ); 733 ret2 = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); 734 ok( ret == ret2, "got %d, expected %d\n", ret, ret2 ); 735 } 736 737 static void test_GetDynamicTimeZoneInformation(void) 738 { 739 DYNAMIC_TIME_ZONE_INFORMATION dyninfo; 740 TIME_ZONE_INFORMATION tzinfo; 741 DWORD ret, ret2; 742 743 if (!pGetDynamicTimeZoneInformation) 744 { 745 win_skip("GetDynamicTimeZoneInformation() is not supported.\n"); 746 return; 747 } 748 749 ret = pGetDynamicTimeZoneInformation(&dyninfo); 750 ret2 = GetTimeZoneInformation(&tzinfo); 751 ok(ret == ret2, "got %d, %d\n", ret, ret2); 752 753 ok(dyninfo.Bias == tzinfo.Bias, "got %d, %d\n", dyninfo.Bias, tzinfo.Bias); 754 ok(!lstrcmpW(dyninfo.StandardName, tzinfo.StandardName), "got std name %s, %s\n", 755 wine_dbgstr_w(dyninfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 756 ok(!memcmp(&dyninfo.StandardDate, &tzinfo.StandardDate, sizeof(dyninfo.StandardDate)), "got different StandardDate\n"); 757 ok(dyninfo.StandardBias == tzinfo.StandardBias, "got %d, %d\n", dyninfo.StandardBias, tzinfo.StandardBias); 758 ok(!lstrcmpW(dyninfo.DaylightName, tzinfo.DaylightName), "got daylight name %s, %s\n", 759 wine_dbgstr_w(dyninfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 760 ok(!memcmp(&dyninfo.DaylightDate, &tzinfo.DaylightDate, sizeof(dyninfo.DaylightDate)), "got different DaylightDate\n"); 761 ok(dyninfo.TimeZoneKeyName[0] != 0, "got empty tz keyname\n"); 762 trace("Dyn TimeZoneKeyName %s\n", wine_dbgstr_w(dyninfo.TimeZoneKeyName)); 763 } 764 765 static ULONGLONG get_longlong_time(FILETIME *time) 766 { 767 ULARGE_INTEGER uli; 768 uli.u.LowPart = time->dwLowDateTime; 769 uli.u.HighPart = time->dwHighDateTime; 770 return uli.QuadPart; 771 } 772 773 static void test_GetSystemTimePreciseAsFileTime(void) 774 { 775 FILETIME ft; 776 ULONGLONG time1, time2; 777 LONGLONG diff; 778 779 if (!pGetSystemTimePreciseAsFileTime) 780 { 781 win_skip("GetSystemTimePreciseAsFileTime() is not supported.\n"); 782 return; 783 } 784 785 GetSystemTimeAsFileTime(&ft); 786 time1 = get_longlong_time(&ft); 787 pGetSystemTimePreciseAsFileTime(&ft); 788 time2 = get_longlong_time(&ft); 789 diff = time2 - time1; 790 if (diff < 0) 791 diff = -diff; 792 ok(diff < 1000000, "Difference between GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime more than 100 ms\n"); 793 794 pGetSystemTimePreciseAsFileTime(&ft); 795 time1 = get_longlong_time(&ft); 796 do { 797 pGetSystemTimePreciseAsFileTime(&ft); 798 time2 = get_longlong_time(&ft); 799 } while (time2 == time1); 800 diff = time2 - time1; 801 ok(diff < 10000 && diff > 0, "GetSystemTimePreciseAsFileTime incremented by more than 1 ms\n"); 802 } 803 804 static void test_GetSystemTimes(void) 805 { 806 807 FILETIME idletime, kerneltime, usertime; 808 int i; 809 ULARGE_INTEGER ul1, ul2, ul3; 810 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi; 811 SYSTEM_BASIC_INFORMATION sbi; 812 ULONG ReturnLength; 813 ULARGE_INTEGER total_usertime, total_kerneltime, total_idletime; 814 815 if (!pGetSystemTimes) 816 { 817 win_skip("GetSystemTimes not available\n"); 818 return; 819 } 820 821 ok( pGetSystemTimes(NULL, NULL, NULL), "GetSystemTimes failed unexpectedly\n" ); 822 823 total_usertime.QuadPart = 0; 824 total_kerneltime.QuadPart = 0; 825 total_idletime.QuadPart = 0; 826 memset( &idletime, 0x11, sizeof(idletime) ); 827 memset( &kerneltime, 0x11, sizeof(kerneltime) ); 828 memset( &usertime, 0x11, sizeof(usertime) ); 829 ok( pGetSystemTimes(&idletime, &kerneltime , &usertime), 830 "GetSystemTimes failed unexpectedly\n" ); 831 832 ul1.LowPart = idletime.dwLowDateTime; 833 ul1.HighPart = idletime.dwHighDateTime; 834 ul2.LowPart = kerneltime.dwLowDateTime; 835 ul2.HighPart = kerneltime.dwHighDateTime; 836 ul3.LowPart = usertime.dwLowDateTime; 837 ul3.HighPart = usertime.dwHighDateTime; 838 839 ok( !NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength), 840 "NtQuerySystemInformation failed\n" ); 841 ok( sizeof(sbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength ); 842 843 /* Check if we have some return values */ 844 trace( "Number of Processors : %d\n", sbi.NumberOfProcessors ); 845 ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", 846 sbi.NumberOfProcessors ); 847 848 sppi = HeapAlloc( GetProcessHeap(), 0, 849 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * sbi.NumberOfProcessors); 850 851 ok( !NtQuerySystemInformation( SystemProcessorPerformanceInformation, sppi, 852 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * sbi.NumberOfProcessors, 853 &ReturnLength), 854 "NtQuerySystemInformation failed\n" ); 855 856 for (i = 0; i < sbi.NumberOfProcessors; i++) 857 { 858 total_usertime.QuadPart += sppi[i].UserTime.QuadPart; 859 total_kerneltime.QuadPart += sppi[i].KernelTime.QuadPart; 860 total_idletime.QuadPart += sppi[i].IdleTime.QuadPart; 861 } 862 863 ok( total_idletime.QuadPart - ul1.QuadPart < 10000000, "test idletime failed\n" ); 864 ok( total_kerneltime.QuadPart - ul2.QuadPart < 10000000, "test kerneltime failed\n" ); 865 ok( total_usertime.QuadPart - ul3.QuadPart < 10000000, "test usertime failed\n" ); 866 867 HeapFree(GetProcessHeap(), 0, sppi); 868 } 869 870 static WORD day_of_month(const SYSTEMTIME* systemtime, WORD year) 871 { 872 SYSTEMTIME first_of_month = {0}; 873 FILETIME filetime; 874 WORD result; 875 876 if (systemtime->wYear != 0) 877 return systemtime->wDay; 878 879 first_of_month.wYear = year; 880 first_of_month.wMonth = systemtime->wMonth; 881 first_of_month.wDay = 1; 882 883 /* round-trip conversion sets day of week field */ 884 SystemTimeToFileTime(&first_of_month, &filetime); 885 FileTimeToSystemTime(&filetime, &first_of_month); 886 887 result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + 888 (7 * (systemtime->wDay - 1)); 889 890 if (systemtime->wDay == 5) 891 { 892 /* make sure this isn't in the next month */ 893 SYSTEMTIME result_date; 894 895 result_date = first_of_month; 896 result_date.wDay = result; 897 898 SystemTimeToFileTime(&result_date, &filetime); 899 FileTimeToSystemTime(&filetime, &result_date); 900 901 if (result_date.wDay != result) 902 result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + 903 (7 * (4 - 1)); 904 } 905 906 return result; 907 } 908 909 static void test_GetTimeZoneInformationForYear(void) 910 { 911 BOOL ret; 912 SYSTEMTIME systemtime; 913 TIME_ZONE_INFORMATION local_tzinfo, tzinfo, tzinfo2; 914 DYNAMIC_TIME_ZONE_INFORMATION dyn_tzinfo; 915 static const WCHAR std_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e',0}; 916 static const WCHAR dlt_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','D','a','y','l','i','g','h','t',' ','T','i','m','e',0}; 917 WORD std_day, dlt_day; 918 919 if (!pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation) 920 { 921 win_skip("GetTimeZoneInformationForYear not available\n"); 922 return; 923 } 924 925 GetLocalTime(&systemtime); 926 927 GetTimeZoneInformation(&local_tzinfo); 928 929 ret = pGetTimeZoneInformationForYear(systemtime.wYear, NULL, &tzinfo); 930 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); 931 ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias); 932 ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), 933 "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 934 ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); 935 ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias); 936 ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), 937 "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 938 ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); 939 ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); 940 941 pGetDynamicTimeZoneInformation(&dyn_tzinfo); 942 943 ret = pGetTimeZoneInformationForYear(systemtime.wYear, &dyn_tzinfo, &tzinfo); 944 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); 945 ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias); 946 ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), 947 "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); 948 ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); 949 ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias); 950 ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), 951 "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); 952 ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); 953 ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); 954 955 memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); 956 lstrcpyW(dyn_tzinfo.TimeZoneKeyName, std_tzname); 957 dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE; 958 959 ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); 960 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); 961 ok(tzinfo.Bias == 180, "Expected Bias 180, got %d\n", tzinfo.Bias); 962 ok(tzinfo.StandardDate.wMonth == 10, "Expected standard month 10, got %d\n", tzinfo.StandardDate.wMonth); 963 std_day = day_of_month(&tzinfo.StandardDate, 2015); 964 ok(std_day == 24, "Expected standard day 24, got %d\n", std_day); 965 ok(tzinfo.StandardBias == 0, "Expected StandardBias 0, got %d\n", tzinfo.StandardBias); 966 ok(tzinfo.DaylightDate.wMonth == 3, "Expected daylight month 3, got %d\n", tzinfo.DaylightDate.wMonth); 967 dlt_day = day_of_month(&tzinfo.DaylightDate, 2015); 968 ok(dlt_day == 28, "Expected daylight day 28, got %d\n", dlt_day); 969 ok(tzinfo.DaylightBias == -60, "Expected DaylightBias -60, got %d\n", tzinfo.DaylightBias); 970 971 ret = pGetTimeZoneInformationForYear(2016, &dyn_tzinfo, &tzinfo2); 972 ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); 973 ok(!lstrcmpW(tzinfo.StandardName, tzinfo2.StandardName), 974 "Got differing StandardName values %s and %s\n", 975 wine_dbgstr_w(tzinfo.StandardName), wine_dbgstr_w(tzinfo2.StandardName)); 976 ok(!lstrcmpW(tzinfo.DaylightName, tzinfo2.DaylightName), 977 "Got differing DaylightName values %s and %s\n", 978 wine_dbgstr_w(tzinfo.DaylightName), wine_dbgstr_w(tzinfo2.DaylightName)); 979 980 memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); 981 lstrcpyW(dyn_tzinfo.TimeZoneKeyName, dlt_tzname); 982 983 SetLastError(0xdeadbeef); 984 ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); 985 ok((ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND) || 986 broken(ret == TRUE) /* vista,7 */, 987 "GetTimeZoneInformationForYear err %u\n", GetLastError()); 988 } 989 990 START_TEST(time) 991 { 992 HMODULE hKernel = GetModuleHandleA("kernel32"); 993 pTzSpecificLocalTimeToSystemTime = (void *)GetProcAddress(hKernel, "TzSpecificLocalTimeToSystemTime"); 994 pSystemTimeToTzSpecificLocalTime = (void *)GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime"); 995 pGetSystemTimes = (void *)GetProcAddress( hKernel, "GetSystemTimes"); 996 pGetCalendarInfoA = (void *)GetProcAddress(hKernel, "GetCalendarInfoA"); 997 pGetCalendarInfoW = (void *)GetProcAddress(hKernel, "GetCalendarInfoW"); 998 pGetDynamicTimeZoneInformation = (void *)GetProcAddress(hKernel, "GetDynamicTimeZoneInformation"); 999 pGetSystemTimePreciseAsFileTime = (void *)GetProcAddress(hKernel, "GetSystemTimePreciseAsFileTime"); 1000 pGetTimeZoneInformationForYear = (void *)GetProcAddress(hKernel, "GetTimeZoneInformationForYear"); 1001 1002 test_conversions(); 1003 test_invalid_arg(); 1004 test_GetTimeZoneInformation(); 1005 test_FileTimeToSystemTime(); 1006 test_FileTimeToLocalFileTime(); 1007 test_TzSpecificLocalTimeToSystemTime(); 1008 test_GetSystemTimes(); 1009 test_FileTimeToDosDateTime(); 1010 test_GetCalendarInfo(); 1011 test_GetDynamicTimeZoneInformation(); 1012 test_GetSystemTimePreciseAsFileTime(); 1013 test_GetTimeZoneInformationForYear(); 1014 } 1015