// function like DosDateTimeToFileTime BOOLEAN FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime) { PDOSTIME pdtime = (PDOSTIME) &DosTime; PDOSDATE pddate = (PDOSDATE) &DosDate; TIME_FIELDS TimeFields; LARGE_INTEGER LocalTime; if (SystemTime == NULL) return FALSE; TimeFields.Milliseconds = 0; TimeFields.Second = pdtime->Second * 2; TimeFields.Minute = pdtime->Minute; TimeFields.Hour = pdtime->Hour; TimeFields.Day = pddate->Day; TimeFields.Month = pddate->Month; TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year); RtlTimeFieldsToTime (&TimeFields, &LocalTime); ExLocalTimeToSystemTime(&LocalTime, SystemTime); return TRUE; }
/* * Here is what we have to do: * * We take in time structure that is > January 1, 1970. * We create a structure that is the first second of January 1, 1970. * Since the From Time is > 1970, to get the number of 100-nanoseconds * since 1970 we just subtract the two dates. * we then have to convert the LARGE_INTEGER to a 32bit integer. */ void ConvertToSecondsFrom1970(CONST PLARGE_INTEGER pFrom, PULONG pTo, PULONG pMillseconds) { TIME_FIELDS tf1970; LARGE_INTEGER t1970, tmp; #if (_WIN32_WINNT == 0x0500) // WIN2k LARGE_INTEGER remainder, divisor; divisor.QuadPart = 10000000; #endif if(!pFrom || !pTo) return; tf1970.Year = 1970; tf1970.Day = 1; tf1970.Hour = 0; tf1970.Minute = 0; tf1970.Second = 1; tf1970.Month = 1; tf1970.Milliseconds = 0; RtlTimeFieldsToTime(&tf1970, &t1970); tmp.QuadPart = pFrom->QuadPart - t1970.QuadPart; *pTo = (ULONG)(*((__int64 *) &tmp) / 10000000U); if(pMillseconds) { #if (_WIN32_WINNT == 0x0500) // WIN2k RtlLargeIntegerDivide(tmp, divisor, &remainder); *pMillseconds = (ULONG)remainder.QuadPart / 1000; #else *pMillseconds = (ULONG)(*((__int64 *) &tmp) % 10000000U) / 1000; #endif } }
LARGE_INTEGER FatFatDateToNtTime ( IN PIRP_CONTEXT IrpContext, IN FAT_DATE FatDate ) /*++ Routine Description: This routine converts a Fat datev value to its corresponding Nt GMT Time value. Arguments: FatDate - Supplies the Fat Date to convert from Return Value: LARGE_INTEGER - Receives the corresponding Nt Time value --*/ { TIME_FIELDS TimeFields; LARGE_INTEGER Time; // // Pack the input time/date into a time field record // TimeFields.Year = (USHORT)(FatDate.Year + 1980); TimeFields.Month = (USHORT)(FatDate.Month); TimeFields.Day = (USHORT)(FatDate.Day); TimeFields.Hour = (USHORT)0; TimeFields.Minute = (USHORT)0; TimeFields.Second = (USHORT)0; TimeFields.Milliseconds = (USHORT)0; // // Convert the time field record to Nt LARGE_INTEGER, and set it to zero // if we were given a bogus time. // if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { Time.LowPart = 0; Time.HighPart = 0; } else { ExLocalTimeToSystemTime( &Time, &Time ); } return Time; UNREFERENCED_PARAMETER( IrpContext ); }
NTSTATUS ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation) { LARGE_INTEGER LocalTime, SystemTime, OldTime; TIME_FIELDS TimeFields; DPRINT("ExpSetTimeZoneInformation() called\n"); DPRINT("Old time zone bias: %d minutes\n", ExpTimeZoneInfo.Bias); DPRINT("Old time zone standard bias: %d minutes\n", ExpTimeZoneInfo.StandardBias); DPRINT("New time zone bias: %d minutes\n", TimeZoneInformation->Bias); DPRINT("New time zone standard bias: %d minutes\n", TimeZoneInformation->StandardBias); /* Get the local time */ HalQueryRealTimeClock(&TimeFields); RtlTimeFieldsToTime(&TimeFields, &LocalTime); /* FIXME: Calculate transition dates */ /* Calculate the bias and set the ID */ ExpTimeZoneBias.QuadPart = ((LONGLONG)(TimeZoneInformation->Bias + TimeZoneInformation->StandardBias)) * TICKSPERMINUTE; ExpTimeZoneId = TIME_ZONE_ID_STANDARD; /* Copy the timezone information */ RtlCopyMemory(&ExpTimeZoneInfo, TimeZoneInformation, sizeof(TIME_ZONE_INFORMATION)); /* Set the new time zone information */ SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart; SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart; SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart; SharedUserData->TimeZoneId = ExpTimeZoneId; DPRINT("New time zone bias: %I64d minutes\n", ExpTimeZoneBias.QuadPart / TICKSPERMINUTE); /* Calculate the new system time */ ExLocalTimeToSystemTime(&LocalTime, &SystemTime); /* Set the new system time */ KeSetSystemTime(&SystemTime, &OldTime, FALSE, NULL); /* Return success */ DPRINT("ExpSetTimeZoneInformation() done\n"); return STATUS_SUCCESS; }
NET_API_STATUS NetpSystemTimeToGmtTime( IN LPSYSTEMTIME WinSplitTime, OUT LPDWORD GmtTime // seconds since 1970 (GMT). ) { TIME_FIELDS NtSplitTime; LARGE_INTEGER NtPreciseTime; if ( (WinSplitTime==NULL) || (GmtTime==NULL) ) { return (ERROR_INVALID_PARAMETER); } NtSplitTime.Year = (CSHORT) WinSplitTime->wYear; NtSplitTime.Month = (CSHORT) WinSplitTime->wMonth; NtSplitTime.Day = (CSHORT) WinSplitTime->wDay; NtSplitTime.Hour = (CSHORT) WinSplitTime->wHour; NtSplitTime.Minute = (CSHORT) WinSplitTime->wMinute; NtSplitTime.Second = (CSHORT) WinSplitTime->wSecond; NtSplitTime.Milliseconds = (CSHORT) WinSplitTime->wMilliseconds; NtSplitTime.Weekday = (CSHORT) WinSplitTime->wDayOfWeek; if ( !RtlTimeFieldsToTime ( & NtSplitTime, // input & NtPreciseTime // output ) ) { NetpKdPrint(( PREFIX_NETLIB "NetpSystemTimeToGmtTime: RtlTimeFieldsToTime failed.\n" )); // BUGBUG: Better error code? Log this? return (NERR_InternalError); } if ( !RtlTimeToSecondsSince1970 ( & NtPreciseTime, // input (PULONG) GmtTime ) ) { NetpKdPrint(( PREFIX_NETLIB "NetpSystemTimeToGmtTime: " "RtlTimeToSecondsSince1970 failed.\n" )); // BUGBUG: Better error code? Log this? return (NERR_InternalError); } return (NO_ERROR); } // NetpSystemTimeToGmtTime
FORCEINLINE VOID FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime, IN PFAT_DATETIME FatDateTime, IN UCHAR TenMs OPTIONAL) { TIME_FIELDS TimeFields; /* Setup time fields */ TimeFields.Year = FatDateTime->Date.Year + 1980; TimeFields.Month = FatDateTime->Date.Month; TimeFields.Day = FatDateTime->Date.Day; TimeFields.Hour = FatDateTime->Time.Hour; TimeFields.Minute = FatDateTime->Time.Minute; TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1); /* Adjust up to 10 milliseconds * if the parameter was supplied */ if (ARGUMENT_PRESENT(TenMs)) { TimeFields.Second += TenMs / 100; TimeFields.Milliseconds = (TenMs % 100) * 10; } else { TimeFields.Milliseconds = 0; } /* Fix seconds value that might get beyoud the bound */ if (TimeFields.Second > 59) TimeFields.Second = 0; /* Perform ceonversion to system time if possible */ if (RtlTimeFieldsToTime(&TimeFields, SystemTime)) { /* Convert to system time */ ExLocalTimeToSystemTime(SystemTime, SystemTime); } else { /* Set to default time if conversion failed */ *SystemTime = FatGlobalData.DefaultFileTime; } }
/********************************************************************* * SystemTimeToFileTime (KERNEL32.@) */ BOOL WINAPI SystemTimeToFileTime( const SYSTEMTIME *syst, LPFILETIME ft ) { TIME_FIELDS tf; LARGE_INTEGER t; TRACEN((printf("SystemTimeToFileTime\n"))) tf.Year = syst->wYear; tf.Month = syst->wMonth; tf.Day = syst->wDay; tf.Hour = syst->wHour; tf.Minute = syst->wMinute; tf.Second = syst->wSecond; tf.Milliseconds = syst->wMilliseconds; RtlTimeFieldsToTime(&tf, &t); ft->dwLowDateTime = (DWORD)t.QuadPart; ft->dwHighDateTime = (DWORD)(t.QuadPart>>32); return TRUE; }
/********************************************************************* * SystemTimeToFileTime (KERNEL32.@) */ BOOL WINAPI SystemTimeToFileTime( const SYSTEMTIME *syst, LPFILETIME ft ) { TIME_FIELDS tf; LARGE_INTEGER t; tf.Year = syst->wYear; tf.Month = syst->wMonth; tf.Day = syst->wDay; tf.Hour = syst->wHour; tf.Minute = syst->wMinute; tf.Second = syst->wSecond; tf.Milliseconds = syst->wMilliseconds; if( !RtlTimeFieldsToTime(&tf, &t)) { SetLastError( ERROR_INVALID_PARAMETER); return FALSE; } ft->dwLowDateTime = t.u.LowPart; ft->dwHighDateTime = t.u.HighPart; return TRUE; }
static BOOL ConvertSystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime) { TIME_FIELDS TimeFields; LARGE_INTEGER liTime; TimeFields.Year = lpSystemTime->wYear; TimeFields.Month = lpSystemTime->wMonth; TimeFields.Day = lpSystemTime->wDay; TimeFields.Hour = lpSystemTime->wHour; TimeFields.Minute = lpSystemTime->wMinute; TimeFields.Second = lpSystemTime->wSecond; TimeFields.Milliseconds = lpSystemTime->wMilliseconds; if (RtlTimeFieldsToTime(&TimeFields, &liTime)) { lpFileTime->dwLowDateTime = liTime.u.LowPart; lpFileTime->dwHighDateTime = liTime.u.HighPart; return TRUE; } return FALSE; }
BOOLEAN FatNtTimeToFatTime ( IN PIRP_CONTEXT IrpContext, IN PLARGE_INTEGER NtTime, IN BOOLEAN Rounding, OUT PFAT_TIME_STAMP FatTime, OUT OPTIONAL PCHAR TenMsecs ) /*++ Routine Description: This routine converts an NtTime value to its corresponding Fat time value. Arguments: NtTime - Supplies the Nt GMT Time value to convert from Rounding - Indicates whether the NT time should be rounded up to a FAT boundary. This should only be done *once* in the lifetime of a timestamp (important for tunneling, which will cause a timestamp to pass through at least twice). If true, rounded up. If false, rounded down to 10ms boundary. This obeys the rules for non-creation time and creation times (respectively). FatTime - Receives the equivalent Fat time value TenMsecs - Optionally receive the number of tens of milliseconds the NtTime, after any rounding, is greater than the FatTime Return Value: BOOLEAN - TRUE if the Nt time value is within the range of Fat's time range, and FALSE otherwise --*/ { TIME_FIELDS TimeFields; // // Convert the input to the a time field record. // if (Rounding) { // // Add almost two seconds to round up to the nearest double second. // NtTime->QuadPart = NtTime->QuadPart + AlmostTwoSeconds; } ExSystemTimeToLocalTime( NtTime, NtTime ); RtlTimeToTimeFields( NtTime, &TimeFields ); // // Check the range of the date found in the time field record // if ((TimeFields.Year < 1980) || (TimeFields.Year > (1980 + 127))) { ExLocalTimeToSystemTime( NtTime, NtTime ); return FALSE; } // // The year will fit in Fat so simply copy over the information // FatTime->Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2); FatTime->Time.Minute = (USHORT)(TimeFields.Minute); FatTime->Time.Hour = (USHORT)(TimeFields.Hour); FatTime->Date.Year = (USHORT)(TimeFields.Year - 1980); FatTime->Date.Month = (USHORT)(TimeFields.Month); FatTime->Date.Day = (USHORT)(TimeFields.Day); if (TenMsecs) { if (!Rounding) { // // If the number of seconds was not divisible by two, then there // is another second of time (1 sec, 3 sec, etc.) Note we round down // the number of milleconds onto tens of milleseconds boundaries. // *TenMsecs = (TimeFields.Milliseconds / 10) + ((TimeFields.Second % 2) * 100); } else { // // If we rounded up, we have in effect changed the NT time. Therefore, // it does not differ from the FAT time. // *TenMsecs = 0; } } if (Rounding) { // // Slice off non-FAT boundary time and convert back to 64bit form // TimeFields.Milliseconds = 0; TimeFields.Second -= TimeFields.Second % 2; } else { // // Round down to 10ms boundary // TimeFields.Milliseconds -= TimeFields.Milliseconds % 10; } // // Convert back to NT time // (VOID) RtlTimeFieldsToTime(&TimeFields, NtTime); ExLocalTimeToSystemTime( NtTime, NtTime ); UNREFERENCED_PARAMETER( IrpContext ); return TRUE; }
LARGE_INTEGER FatFatTimeToNtTime ( IN PIRP_CONTEXT IrpContext, IN FAT_TIME_STAMP FatTime, IN UCHAR TenMilliSeconds ) /*++ Routine Description: This routine converts a Fat time value pair to its corresponding Nt GMT Time value. Arguments: FatTime - Supplies the Fat Time to convert from TenMilliSeconds - A 10 Milisecond resolution Return Value: LARGE_INTEGER - Receives the corresponding Nt GMT Time value --*/ { TIME_FIELDS TimeFields; LARGE_INTEGER Time; // // Pack the input time/date into a time field record // TimeFields.Year = (USHORT)(FatTime.Date.Year + 1980); TimeFields.Month = (USHORT)(FatTime.Date.Month); TimeFields.Day = (USHORT)(FatTime.Date.Day); TimeFields.Hour = (USHORT)(FatTime.Time.Hour); TimeFields.Minute = (USHORT)(FatTime.Time.Minute); TimeFields.Second = (USHORT)(FatTime.Time.DoubleSeconds * 2); if (TenMilliSeconds != 0) { TimeFields.Second += (USHORT)(TenMilliSeconds / 100); TimeFields.Milliseconds = (USHORT)((TenMilliSeconds % 100) * 10); } else { TimeFields.Milliseconds = (USHORT)0; } // // If the second value is greater than 59 then we truncate it to 0. // Note that this can't happen with a proper FAT timestamp. // if (TimeFields.Second > 59) { TimeFields.Second = 0; } // // Convert the time field record to Nt LARGE_INTEGER, and set it to zero // if we were given a bogus time. // if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { Time.LowPart = 0; Time.HighPart = 0; } else { ExLocalTimeToSystemTime( &Time, &Time ); } return Time; UNREFERENCED_PARAMETER( IrpContext ); }
static HRESULT WINAPI MSTASK_ITaskTrigger_SetTrigger( ITaskTrigger* iface, const PTASK_TRIGGER pTrigger) { TaskTriggerImpl * This = impl_from_ITaskTrigger(iface); TIME_FIELDS field_time; LARGE_INTEGER sys_time; TASK_TRIGGER tmp_trigger_cond; TRACE("(%p, %p)\n", iface, pTrigger); /* Verify valid structure size */ if (pTrigger->cbTriggerSize != sizeof(*pTrigger)) return E_INVALIDARG; tmp_trigger_cond.cbTriggerSize = pTrigger->cbTriggerSize; /* Reserved field must be zero */ tmp_trigger_cond.Reserved1 = 0; /* Verify and set valid start date and time */ memset(&field_time, 0, sizeof(field_time)); field_time.Year = pTrigger->wBeginYear; field_time.Month = pTrigger->wBeginMonth; field_time.Day = pTrigger->wBeginDay; field_time.Hour = pTrigger->wStartHour; field_time.Minute = pTrigger->wStartMinute; if (!RtlTimeFieldsToTime(&field_time, &sys_time)) return E_INVALIDARG; tmp_trigger_cond.wBeginYear = pTrigger->wBeginYear; tmp_trigger_cond.wBeginMonth = pTrigger->wBeginMonth; tmp_trigger_cond.wBeginDay = pTrigger->wBeginDay; tmp_trigger_cond.wStartHour = pTrigger->wStartHour; tmp_trigger_cond.wStartMinute = pTrigger->wStartMinute; /* Verify valid end date if TASK_TRIGGER_FLAG_HAS_END_DATE flag is set */ if (pTrigger->rgFlags & TASK_TRIGGER_FLAG_HAS_END_DATE) { memset(&field_time, 0, sizeof(field_time)); field_time.Year = pTrigger->wEndYear; field_time.Month = pTrigger->wEndMonth; field_time.Day = pTrigger->wEndDay; if (!RtlTimeFieldsToTime(&field_time, &sys_time)) return E_INVALIDARG; } /* Set valid end date independent of TASK_TRIGGER_FLAG_HAS_END_DATE flag */ tmp_trigger_cond.wEndYear = pTrigger->wEndYear; tmp_trigger_cond.wEndMonth = pTrigger->wEndMonth; tmp_trigger_cond.wEndDay = pTrigger->wEndDay; /* Verify duration and interval pair */ if (pTrigger->MinutesDuration <= pTrigger->MinutesInterval && pTrigger->MinutesInterval > 0) return E_INVALIDARG; tmp_trigger_cond.MinutesDuration = pTrigger->MinutesDuration; tmp_trigger_cond.MinutesInterval = pTrigger->MinutesInterval; /* Copy over flags */ tmp_trigger_cond.rgFlags = pTrigger->rgFlags; /* Set TriggerType dependent fields of Type union */ tmp_trigger_cond.TriggerType = pTrigger->TriggerType; switch (pTrigger->TriggerType) { case TASK_TIME_TRIGGER_DAILY: tmp_trigger_cond.Type.Daily.DaysInterval = pTrigger->Type.Daily.DaysInterval; break; case TASK_TIME_TRIGGER_WEEKLY: tmp_trigger_cond.Type.Weekly.WeeksInterval = pTrigger->Type.Weekly.WeeksInterval; tmp_trigger_cond.Type.Weekly.rgfDaysOfTheWeek = pTrigger->Type.Weekly.rgfDaysOfTheWeek; break; case TASK_TIME_TRIGGER_MONTHLYDATE: tmp_trigger_cond.Type.MonthlyDate.rgfDays = pTrigger->Type.MonthlyDate.rgfDays; tmp_trigger_cond.Type.MonthlyDate.rgfMonths = pTrigger->Type.MonthlyDate.rgfMonths; break; case TASK_TIME_TRIGGER_MONTHLYDOW: tmp_trigger_cond.Type.MonthlyDOW.wWhichWeek = pTrigger->Type.MonthlyDOW.wWhichWeek; tmp_trigger_cond.Type.MonthlyDOW.rgfDaysOfTheWeek = pTrigger->Type.MonthlyDOW.rgfDaysOfTheWeek; tmp_trigger_cond.Type.MonthlyDOW.rgfMonths = pTrigger->Type.MonthlyDOW.rgfMonths; break; case TASK_TIME_TRIGGER_ONCE: case TASK_EVENT_TRIGGER_ON_IDLE: case TASK_EVENT_TRIGGER_AT_SYSTEMSTART: case TASK_EVENT_TRIGGER_AT_LOGON: default: tmp_trigger_cond.Type = This->triggerCond.Type; break; } /* Reserved field must be zero */ tmp_trigger_cond.Reserved2 = 0; /* wRandomMinutesInterval not currently used and is initialized to zero */ tmp_trigger_cond.wRandomMinutesInterval = 0; /* Update object copy of triggerCond */ This->triggerCond = tmp_trigger_cond; return S_OK; }
int main( int argc, char *argv[] ) { ULONG i; // // We're starting the test // DbgPrint("Start Time Test\n"); // // Start by initializing some constants and making sure they // are correct // Zero.QuadPart = 0; OneSecond.QuadPart = 10000000; OneMinute.QuadPart = OneSecond.QuadPart * 60; OneHour.QuadPart = OneMinute.QuadPart * 60; OneDay.QuadPart = OneHour.QuadPart * 24; OneWeek.QuadPart = OneDay.QuadPart * 7; OneNormalYear.QuadPart = OneDay.QuadPart * 365; OneLeapYear.QuadPart = OneDay.QuadPart * 366; OneCentury.QuadPart = (OneNormalYear.QuadPart * 76) + (OneLeapYear.QuadPart * 24); TwoCenturies.QuadPart = OneCentury.QuadPart * 2; ThreeCenturies.QuadPart = OneCentury.QuadPart * 3; FourCenturies.QuadPart = (OneCentury.QuadPart * 4) + OneDay.QuadPart; Sum.QuadPart = Zero.QuadPart + OneSecond.QuadPart + OneMinute.QuadPart + OneHour.QuadPart + OneDay.QuadPart + OneWeek.QuadPart + OneNormalYear.QuadPart + ThreeCenturies.QuadPart; RtlTimeToTimeFields( (PLARGE_INTEGER)&Zero, &TimeFields ); DbgPrint("StartOf1601 = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to Zero\n"); } if ((Time.LowPart != Zero.LowPart) || (Time.HighPart != Zero.HighPart)) { DbgPrint("****ERROR Time != Zero\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneSecond, &TimeFields ); DbgPrint(" + 1 Second = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneSecond\n"); } if ((Time.LowPart != OneSecond.LowPart) || (Time.HighPart != OneSecond.HighPart)) { DbgPrint("****ERROR Time != OneSecond\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneMinute, &TimeFields ); DbgPrint(" + 1 Minute = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneMinute\n"); } if ((Time.LowPart != OneMinute.LowPart) || (Time.HighPart != OneMinute.HighPart)) { DbgPrint("****ERROR Time != OneMinute\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneHour, &TimeFields ); DbgPrint(" + 1 Hour = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneHour\n"); } if ((Time.LowPart != OneHour.LowPart) || (Time.HighPart != OneHour.HighPart)) { DbgPrint("****ERROR Time != OneHour\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneDay, &TimeFields ); DbgPrint(" + 1 Day = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneDay\n"); } if ((Time.LowPart != OneDay.LowPart) || (Time.HighPart != OneDay.HighPart)) { DbgPrint("****ERROR Time != OneDay\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneWeek, &TimeFields ); DbgPrint(" + 1 Week = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneWeek\n"); } if ((Time.LowPart != OneWeek.LowPart) || (Time.HighPart != OneWeek.HighPart)) { DbgPrint("****ERROR Time != OneWeek\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneNormalYear, &TimeFields ); DbgPrint(" + 1 NormalYear = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneNormalYear\n"); } if ((Time.LowPart != OneNormalYear.LowPart) || (Time.HighPart != OneNormalYear.HighPart)) { DbgPrint("****ERROR Time != OneNormalYear\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneLeapYear, &TimeFields ); DbgPrint(" + 1 LeapYear = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneLeapYear\n"); } if ((Time.LowPart != OneLeapYear.LowPart) || (Time.HighPart != OneLeapYear.HighPart)) { DbgPrint("****ERROR Time != OneLeapYear\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&OneCentury, &TimeFields ); DbgPrint(" + 1 Century = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to OneCentury\n"); } if ((Time.LowPart != OneCentury.LowPart) || (Time.HighPart != OneCentury.HighPart)) { DbgPrint("****ERROR Time != OneCentury\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&TwoCenturies, &TimeFields ); DbgPrint(" + 2 Centuries = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to TwoCenturies\n"); } if ((Time.LowPart != TwoCenturies.LowPart) || (Time.HighPart != TwoCenturies.HighPart)) { DbgPrint("****ERROR Time != TwoCenturies\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&ThreeCenturies, &TimeFields ); DbgPrint(" + 3 Centuries = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to ThreeCenturies\n"); } if ((Time.LowPart != ThreeCenturies.LowPart) || (Time.HighPart != ThreeCenturies.HighPart)) { DbgPrint("****ERROR Time != ThreeCenturies\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&FourCenturies, &TimeFields ); DbgPrint(" + 4 Centuries = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to FourCenturies\n"); } if ((Time.LowPart != FourCenturies.LowPart) || (Time.HighPart != FourCenturies.HighPart)) { DbgPrint("****ERROR Time != FourCenturies\n"); } RtlTimeToTimeFields( (PLARGE_INTEGER)&Sum, &TimeFields ); DbgPrint(" + sum = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to Sum\n"); } if ((Time.LowPart != Sum.LowPart) || (Time.HighPart != Sum.HighPart)) { DbgPrint("****ERROR Time != Sum\n"); } DbgPrint("\n"); // // Setup and test the start 1970 time // RtlSecondsSince1970ToTime( 0, &StartOf1970 ); RtlTimeToTimeFields( &StartOf1970, &TimeFields ); DbgPrint(" Start of 1970 = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to start of 1970\n"); } if ((Time.LowPart != StartOf1970.LowPart) || (Time.HighPart != StartOf1970.HighPart)) { DbgPrint("****ERROR Time != StartOf1970\n"); } if (!RtlTimeToSecondsSince1970( &StartOf1970, &i )) { DbgPrint("****ERROR converting time to seconds since 1970\n"); } if (i != 0) { DbgPrint("****ERROR seconds since 1970 != 0\n"); } // // Setup and test the start 1980 time // RtlSecondsSince1980ToTime( 0, &StartOf1980 ); RtlTimeToTimeFields( &StartOf1980, &TimeFields ); DbgPrint(" Start of 1980 = "); PrintTimeFields( &TimeFields ); DbgPrint("\n"); if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields back to start of 1980\n"); } if ((Time.LowPart != StartOf1980.LowPart) || (Time.HighPart != StartOf1980.HighPart)) { DbgPrint("****ERROR Time != StartOf1980\n"); } if (!RtlTimeToSecondsSince1980( &StartOf1980, &i )) { DbgPrint("****ERROR converting time to seconds since 1980\n"); } if (i != 0) { DbgPrint("****ERROR seconds since 1980 != 0\n"); } // // Lets try to print the Christmas when Santa arrives for 1901 to 2001 // every 10 years // TimeFields.Month = 12; TimeFields.Day = 25; TimeFields.Hour = 3; TimeFields.Minute = 30; TimeFields.Second = 15; TimeFields.Milliseconds = 250; for (i = 1901; i < 2002; i += 10) { TimeFields.Year = i; if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields to Christmas %4d\n", TimeFields.Year); } RtlTimeToTimeFields( &Time, &TimeFields ); DbgPrint(" Christmas %4d = ", i); PrintTimeFields( &TimeFields ); DbgPrint("\n"); } // // Let's see how old I really am, when I turn 10, 20, 30, ... // TimeFields.Month = 12; TimeFields.Day = 5; TimeFields.Hour = 3; TimeFields.Minute = 14; TimeFields.Second = 0; TimeFields.Milliseconds = 0; for (i = 1956; i <= 1956+60; i += 10) { TimeFields.Year = i; if (!RtlTimeFieldsToTime( &TimeFields, &Time )) { DbgPrint("****ERROR converting TimeFields to DOB %4d\n", TimeFields.Year); } RtlTimeToTimeFields( &Time, &TimeFields ); DbgPrint(" DOB + %4d = ", i-1956); PrintTimeFields( &TimeFields ); DbgPrint("\n"); } DbgPrint("End Time Test\n"); return TRUE; }
/* * @implemented */ BOOLEAN NTAPI RtlCutoverTimeToSystemTime(IN PTIME_FIELDS CutoverTimeFields, OUT PLARGE_INTEGER SystemTime, IN PLARGE_INTEGER CurrentTime, IN BOOLEAN ThisYearsCutoverOnly) { TIME_FIELDS AdjustedTimeFields; TIME_FIELDS CurrentTimeFields; TIME_FIELDS CutoverSystemTimeFields; LARGE_INTEGER CutoverSystemTime; UCHAR MonthLength; CSHORT Days; BOOLEAN NextYearsCutover = FALSE; /* Check fixed cutover time */ if (CutoverTimeFields->Year != 0) { if (!RtlTimeFieldsToTime(CutoverTimeFields, SystemTime)) return FALSE; if (SystemTime->QuadPart < CurrentTime->QuadPart) return FALSE; return TRUE; } /* * Compute recurring cutover time */ /* Day must be between 1(first) and 5(last) */ if (CutoverTimeFields->Day == 0 || CutoverTimeFields->Day > 5) return FALSE; RtlTimeToTimeFields(CurrentTime, &CurrentTimeFields); while (TRUE) { /* Compute the cutover time of the first day of the current month */ AdjustedTimeFields.Year = CurrentTimeFields.Year; if (NextYearsCutover) AdjustedTimeFields.Year++; AdjustedTimeFields.Month = CutoverTimeFields->Month; AdjustedTimeFields.Day = 1; AdjustedTimeFields.Hour = CutoverTimeFields->Hour; AdjustedTimeFields.Minute = CutoverTimeFields->Minute; AdjustedTimeFields.Second = CutoverTimeFields->Second; AdjustedTimeFields.Milliseconds = CutoverTimeFields->Milliseconds; if (!RtlTimeFieldsToTime(&AdjustedTimeFields, &CutoverSystemTime)) return FALSE; RtlTimeToTimeFields(&CutoverSystemTime, &CutoverSystemTimeFields); /* Adjust day to first matching weekday */ if (CutoverSystemTimeFields.Weekday != CutoverTimeFields->Weekday) { if (CutoverSystemTimeFields.Weekday < CutoverTimeFields->Weekday) Days = CutoverTimeFields->Weekday - CutoverSystemTimeFields.Weekday; else Days = DAYSPERWEEK - (CutoverSystemTimeFields.Weekday - CutoverTimeFields->Weekday); AdjustedTimeFields.Day += Days; } /* Adjust the number of weeks */ if (CutoverTimeFields->Day > 1) { Days = DAYSPERWEEK * (CutoverTimeFields->Day - 1); MonthLength = MonthLengths[IsLeapYear(AdjustedTimeFields.Year)][AdjustedTimeFields.Month - 1]; if ((AdjustedTimeFields.Day + Days) > MonthLength) Days -= DAYSPERWEEK; AdjustedTimeFields.Day += Days; } if (!RtlTimeFieldsToTime(&AdjustedTimeFields, &CutoverSystemTime)) return FALSE; if (ThisYearsCutoverOnly || NextYearsCutover || CutoverSystemTime.QuadPart >= CurrentTime->QuadPart) { break; } NextYearsCutover = TRUE; } SystemTime->QuadPart = CutoverSystemTime.QuadPart; return TRUE; }