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