#include "stdafx.h" #include #include "helper.h" /////////////////////////////////////////////////////////////////////////////// // // Portion copy from private\ntos\rtl\time.c // /////////////////////////////////////////////////////////////////////////////// // // ULONG // NumberOfLeapYears ( // IN ULONG ElapsedYears // ); // // The number of leap years is simply the number of years divided by 4 // minus years divided by 100 plus years divided by 400. This says // that every four years is a leap year except centuries, and the // exception to the exception is the quadricenturies // #define NumberOfLeapYears(YEARS) ( \ ((YEARS) / 4) - ((YEARS) / 100) + ((YEARS) / 400) \ ) // // ULONG // ElapsedYearsToDays ( // IN ULONG ElapsedYears // ); // // The number of days contained in elapsed years is simply the number // of years times 365 (because every year has at least 365 days) plus // the number of leap years there are (i.e., the number of 366 days years) // #define ElapsedYearsToDays(YEARS) ( \ ((YEARS) * 365) + NumberOfLeapYears(YEARS) \ ) // // BOOLEAN // IsLeapYear ( // IN ULONG ElapsedYears // ); // // If it is an even 400 or a non century leapyear then the // answer is true otherwise it's false // #define IsLeapYear(YEARS) ( \ (((YEARS) % 400 == 0) || \ ((YEARS) % 100 != 0) && ((YEARS) % 4 == 0)) ? \ TRUE \ : \ FALSE \ ) // // ULONG // MaxDaysInMonth ( // IN ULONG Year, // IN ULONG Month // ); // // The maximum number of days in a month depend on the year and month. // It is the difference between the days to the month and the days // to the following month // #define MaxDaysInMonth(YEAR,MONTH) ( \ IsLeapYear(YEAR) ? \ LeapYearDaysPrecedingMonth[(MONTH) + 1] - \ LeapYearDaysPrecedingMonth[(MONTH)] \ : \ NormalYearDaysPrecedingMonth[(MONTH) + 1] - \ NormalYearDaysPrecedingMonth[(MONTH)] \ ) #define ConvertDaysToMilliseconds(DAYS) ( \ Int32x32To64( (DAYS), 86400000 ) \ ) // // The following two tables map a month index to the number of days preceding // the month in the year. Both tables are zero based. For example, 1 (Feb) // has 31 days preceding it. To help calculate the maximum number of days // in a month each table has 13 entries, so the number of days in a month // of index i is the table entry of i+1 minus the table entry of i. // CONST USHORT LeapYearDaysPrecedingMonth[13] = { 0, // January 31, // February 31+29, // March 31+29+31, // April 31+29+31+30, // May 31+29+31+30+31, // June 31+29+31+30+31+30, // July 31+29+31+30+31+30+31, // August 31+29+31+30+31+30+31+31, // September 31+29+31+30+31+30+31+31+30, // October 31+29+31+30+31+30+31+31+30+31, // November 31+29+31+30+31+30+31+31+30+31+30, // December 31+29+31+30+31+30+31+31+30+31+30+31}; CONST USHORT NormalYearDaysPrecedingMonth[13] = { 0, // January 31, // February 31+28, // March 31+28+31, // April 31+28+31+30, // May 31+28+31+30+31, // June 31+28+31+30+31+30, // July 31+28+31+30+31+30+31, // August 31+28+31+30+31+30+31+31, // September 31+28+31+30+31+30+31+31+30, // October 31+28+31+30+31+30+31+31+30+31, // November 31+28+31+30+31+30+31+31+30+31+30, // December 31+28+31+30+31+30+31+31+30+31+30+31}; // // These are known constants used to convert 1970 and 1980 times to 1601 // times. They are the number of seconds from the 1601 base to the start // of 1970 and the start of 1980. The number of seconds from 1601 to // 1970 is 369 years worth, or (369 * 365) + 89 leap days = 134774 days, or // 134774 * 864000 seconds, which is equal to the large integer defined // below. The number of seconds from 1601 to 1980 is 379 years worth, or etc. // const LARGE_INTEGER SecondsToStartOf1970 = {0xb6109100, 0x00000002}; const LARGE_INTEGER SecondsToStartOf1980 = {0xc8df3700, 0x00000002}; /////////////////////////////////////////////////////////////////////////////// // // Above portion copy from private\ntos\rtl\time.c // // /////////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- void ConvertInt64ToFileTime( const __int64* pint64, FILETIME* pft ) /*++ --*/ { pft->dwLowDateTime = (DWORD)(*pint64 & 0xFFFFFFFF); pft->dwHighDateTime = (LONG) (*pint64 >> 32); return; } //--------------------------------------------------------------------------- void ConvertFileTimeToInt64( const FILETIME* pft, __int64* pint64 ) /*++ --*/ { ULARGE_INTEGER ul; ul.LowPart = pft->dwLowDateTime; ul.HighPart = pft->dwHighDateTime; *pint64 = (__int64)ul.QuadPart; return; } //--------------------------------------------------------------------------- void ConvertInt64ToUlargeInt( const __int64* pint64, ULARGE_INTEGER* pularge ) /*++ --*/ { pularge->QuadPart = *pint64; return; } //--------------------------------------------------------------------------- BOOL MyMkTime( SYSTEMTIME* psysTime, FILETIME* pft ) /*++ Similar to standard C runtime mktime() except it operate on SYSTEMTIME, note, BUG in mktime() that it lost one day, e.g, add 9 year, 25 months to 1970/1/1, mktime returns 1981/1/31 instead of 1981/2/1 --*/ { DWORD dwMilliseconds; ULARGE_INTEGER ul100NsSince1970; LONGLONG ul100NsSince1601; LONGLONG ul100Ns; FILETIME ft; BOOL bSuccess; DWORD dwDaysSince1970; // // day/hour/mins/second to 100ns dwMilliseconds = ((psysTime->wHour * 60 + psysTime->wMinute) * 60 + psysTime->wSecond) * 1000 + psysTime->wMilliseconds; ul100Ns = UInt32x32To64( dwMilliseconds, 10000 ); // // Convert year/month/day to days since 1980 while( psysTime->wMonth > 12 ) { // our month is inclusive psysTime->wYear ++; psysTime->wMonth -= 12; } dwDaysSince1970 = ElapsedYearsToDays(psysTime->wYear) - ElapsedYearsToDays(1970); // dwDaysSince1970 already included 1/1/1970 dwDaysSince1970 += psysTime->wDay - 1; if(IsLeapYear(psysTime->wYear) == TRUE) { dwDaysSince1970 += LeapYearDaysPrecedingMonth[psysTime->wMonth - 1]; dwDaysSince1970--; } else { dwDaysSince1970 += NormalYearDaysPrecedingMonth[psysTime->wMonth - 1]; } // // Convert days since 1980 to 100 ns since 1980 ul100NsSince1601 = ConvertDaysToMilliseconds(dwDaysSince1970) * 10000 + ul100Ns; ul100NsSince1601 += (SecondsToStartOf1970.QuadPart * 10000000); ConvertInt64ToFileTime(&ul100NsSince1601, &ft); bSuccess = FileTimeToSystemTime( &ft, psysTime ); if(bSuccess == TRUE && pft != NULL) { *pft = ft; } return bSuccess; }