From 1c6cb382bce61ca08ef697230a7300185de68a88 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 25 Mar 2004 00:12:40 +0000 Subject: [PATCH] Correct errors with move to kernel time functions. Add test case. --- dlls/msvcrt/tests/.cvsignore | 1 + dlls/msvcrt/tests/Makefile.in | 3 +- dlls/msvcrt/tests/time.c | 121 ++++++++++++++++++++++++++++++++++ dlls/msvcrt/time.c | 22 +++---- 4 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 dlls/msvcrt/tests/time.c diff --git a/dlls/msvcrt/tests/.cvsignore b/dlls/msvcrt/tests/.cvsignore index b660324acf4..1d08f6518ab 100644 --- a/dlls/msvcrt/tests/.cvsignore +++ b/dlls/msvcrt/tests/.cvsignore @@ -5,3 +5,4 @@ heap.ok scanf.ok string.ok testlist.c +time.ok diff --git a/dlls/msvcrt/tests/Makefile.in b/dlls/msvcrt/tests/Makefile.in index 9e604b5f201..d940f6be27f 100644 --- a/dlls/msvcrt/tests/Makefile.in +++ b/dlls/msvcrt/tests/Makefile.in @@ -11,7 +11,8 @@ CTESTS = \ file.c \ heap.c \ scanf.c \ - string.c + string.c \ + time.c @MAKE_TEST_RULES@ diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c new file mode 100644 index 00000000000..fd10a8b262e --- /dev/null +++ b/dlls/msvcrt/tests/time.c @@ -0,0 +1,121 @@ +/* + * Unit test suite for time functions. + * + * Copyright 2004 Uwe Bonnes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "wine/test.h" +#include "winbase.h" +#include "time.h" + +#include /*setenv*/ +#include /*printf*/ + +#define SECSPERDAY 86400 +#define SECSPERHOUR 3600 +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 + +static void test_gmtime() +{ + time_t gmt = (time_t)NULL; + struct tm* gmt_tm = gmtime(&gmt); + if(gmt_tm == 0) + { + ok(0,"gmtime() error\n"); + return; + } + ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon == 0) && (gmt_tm->tm_yday == 0) && + (gmt_tm->tm_mday == 1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour == 0) && + (gmt_tm->tm_min == 0) && (gmt_tm->tm_sec == 0) && (gmt_tm->tm_isdst == 0)), + "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n", + gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday, + gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst); + +} +static void test_mktime() +{ + TIME_ZONE_INFORMATION tzinfo; + DWORD res = GetTimeZoneInformation(&tzinfo); + struct tm my_tm; + time_t nulltime, local_time; + char TZ_env[256]; + int secs; + + ok (res != 0, "GetTimeZoneInformation faile\n"); + /* Bias may be positive or negative, to use offset of one day */ + secs= SECSPERDAY - tzinfo.Bias*SECSPERMIN; + my_tm.tm_mday = 1 + secs/SECSPERDAY; + secs = secs % SECSPERDAY; + my_tm.tm_hour = secs / SECSPERHOUR; + secs = secs % SECSPERHOUR; + my_tm.tm_min = secs / SECSPERMIN; + secs = secs % SECSPERMIN; + my_tm.tm_sec = secs; + + my_tm.tm_year = 70; + my_tm.tm_mon = 0; + my_tm.tm_isdst= 0; + + local_time = mktime(&my_tm); + ok(((DWORD)local_time == SECSPERDAY), "mktime returned 0x%08lx\n",(DWORD)local_time); + + /* TEST that we are indepentant from the TZ variable */ + /*Argh, msvcrt doesn't have setenv() */ + _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):"")); + putenv("TZ=GMT"); + nulltime = mktime(&my_tm); + ok(((DWORD)nulltime == SECSPERDAY),"mktime returned 0x%08lx\n",(DWORD)nulltime); + putenv(TZ_env); +} +static void test_localtime() +{ + TIME_ZONE_INFORMATION tzinfo; + DWORD res = GetTimeZoneInformation(&tzinfo); + time_t gmt = (time_t)(SECSPERDAY + tzinfo.Bias*SECSPERMIN); + char TZ_env[256]; + struct tm* lt; + + ok (res != 0, "GetTimeZoneInformation faile\n"); + lt = localtime(&gmt); + ok(((lt->tm_year == 70) && (lt->tm_mon == 0) && (lt->tm_yday == 1) && + (lt->tm_mday == 2) && (lt->tm_wday == 5) && (lt->tm_hour == 0) && + (lt->tm_min == 0) && (lt->tm_sec == 0) && (lt->tm_isdst == 0)), + "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n", + lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, + lt->tm_min, lt->tm_sec, lt->tm_isdst); + + _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):"")); + putenv("TZ=GMT"); + lt = localtime(&gmt); + ok(((lt->tm_year == 70) && (lt->tm_mon == 0) && (lt->tm_yday == 1) && + (lt->tm_mday == 2) && (lt->tm_wday == 5) && (lt->tm_hour == 0) && + (lt->tm_min == 0) && (lt->tm_sec == 0) && (lt->tm_isdst == 0)), + "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n", + lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour, + lt->tm_min, lt->tm_sec, lt->tm_isdst); + putenv(TZ_env); +} + + +START_TEST(time) +{ + test_gmtime(); + test_mktime(); + test_localtime(); +} diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 35e08646e92..42ff2be9dc6 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -71,11 +71,12 @@ MSVCRT_time_t MSVCRT_mktime(struct MSVCRT_tm *t) FILETIME lft, uft; ULONGLONG time; + st.wMilliseconds = 0; st.wSecond = t->tm_sec; st.wMinute = t->tm_min; st.wHour = t->tm_hour; - st.wDay = t->tm_mday - 1; - st.wMonth = t->tm_mon; + st.wDay = t->tm_mday; + st.wMonth = t->tm_mon + 1; st.wYear = t->tm_year + 1900; SystemTimeToFileTime(&st, &lft); @@ -114,14 +115,14 @@ struct MSVCRT_tm* MSVCRT_localtime(const MSVCRT_time_t* secs) tm.tm_hour = st.wHour; tm.tm_mday = st.wDay; tm.tm_year = st.wYear - 1900; - tm.tm_mon = st.wMonth + 1; + tm.tm_mon = st.wMonth - 1; tm.tm_wday = st.wDayOfWeek; - for (i = 0; i < st.wMonth; i++) { + for (i = tm.tm_yday = 0; i < st.wMonth - 1; i++) { tm.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i]; } - tm.tm_yday += st.wDay; + tm.tm_yday += st.wDay - 1; tzid = GetTimeZoneInformation(&tzinfo); @@ -138,7 +139,7 @@ struct MSVCRT_tm* MSVCRT_gmtime(const MSVCRT_time_t* secs) { int i; - FILETIME ft, lft; + FILETIME ft; SYSTEMTIME st; ULONGLONG time = *secs * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; @@ -146,7 +147,7 @@ struct MSVCRT_tm* MSVCRT_gmtime(const MSVCRT_time_t* secs) ft.dwHighDateTime = (UINT)(time >> 32); ft.dwLowDateTime = (UINT)time; - FileTimeToSystemTime(&lft, &st); + FileTimeToSystemTime(&ft, &st); if (st.wYear < 1970) return NULL; @@ -155,14 +156,13 @@ struct MSVCRT_tm* MSVCRT_gmtime(const MSVCRT_time_t* secs) tm.tm_hour = st.wHour; tm.tm_mday = st.wDay; tm.tm_year = st.wYear - 1900; - tm.tm_mon = st.wMonth + 1; + tm.tm_mon = st.wMonth - 1; tm.tm_wday = st.wDayOfWeek; - - for (i = 0; i < st.wMonth; i++) { + for (i = tm.tm_yday = 0; i < st.wMonth - 1; i++) { tm.tm_yday += MonthLengths[IsLeapYear(st.wYear)][i]; } - tm.tm_yday += st.wDay; + tm.tm_yday += st.wDay - 1; tm.tm_isdst = 0; return &tm;