test: time.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# time.c File Reference

`#include "ntrtlp.h"`

Go to the source code of this file.

## Defines

#define | WEEKDAY_OF_1601 1
#define | SHIFT10000 13
#define | SHIFT10000000 23
#define | SHIFT86400000 26
#define | Convert100nsToMilliseconds(LARGE_INTEGER)
#define | ConvertMillisecondsTo100ns(MILLISECONDS)
#define | Convert100nsToSeconds(LARGE_INTEGER)
#define | ConvertSecondsTo100ns(SECONDS)
#define | ConvertMillisecondsToDays(LARGE_INTEGER)
#define | ConvertDaysToMilliseconds(DAYS)
#define | NumberOfLeapYears(YEARS)
#define | ElapsedYearsToDays(YEARS)
#define | IsLeapYear(YEARS)
#define | MaxDaysInMonth(YEAR, MONTH)

## Functions

ULONG | ElapsedDaysToYears (IN ULONG ElapsedDays)
VOID | TimeToDaysAndFraction (IN PLARGE_INTEGER Time, OUT PULONG ElapsedDays, OUT PULONG Milliseconds)
VOID | DaysAndFractionToTime (IN ULONG ElapsedDays, IN ULONG Milliseconds, OUT PLARGE_INTEGER Time)
VOID | RtlTimeToTimeFields (IN PLARGE_INTEGER Time, OUT PTIME_FIELDS TimeFields)
BOOLEAN | RtlCutoverTimeToSystemTime (PTIME_FIELDS CutoverTime, PLARGE_INTEGER SystemTime, PLARGE_INTEGER CurrentSystemTime, BOOLEAN ThisYear)
BOOLEAN | RtlTimeFieldsToTime (IN PTIME_FIELDS TimeFields, OUT PLARGE_INTEGER Time)
VOID | RtlTimeToElapsedTimeFields (IN PLARGE_INTEGER Time, OUT PTIME_FIELDS TimeFields)
BOOLEAN | RtlTimeToSecondsSince1980 (IN PLARGE_INTEGER Time, OUT PULONG ElapsedSeconds)
VOID | RtlSecondsSince1980ToTime (IN ULONG ElapsedSeconds, OUT PLARGE_INTEGER Time)
BOOLEAN | RtlTimeToSecondsSince1970 (IN PLARGE_INTEGER Time, OUT PULONG ElapsedSeconds)
VOID | RtlSecondsSince1970ToTime (IN ULONG ElapsedSeconds, OUT PLARGE_INTEGER Time)
NTSTATUS | RtlSystemTimeToLocalTime (IN PLARGE_INTEGER SystemTime, OUT PLARGE_INTEGER LocalTime)
NTSTATUS | RtlLocalTimeToSystemTime (IN PLARGE_INTEGER LocalTime, OUT PLARGE_INTEGER SystemTime)

## Variables

CONST UCHAR | LeapYearDayToMonth [366]
CONST UCHAR | NormalYearDayToMonth [365]
CONST CSHORT | LeapYearDaysPrecedingMonth [13]
CONST CSHORT | NormalYearDaysPrecedingMonth [13]
const LARGE_INTEGER | SecondsToStartOf1970 = {0xb6109100, 0x00000002}
const LARGE_INTEGER | SecondsToStartOf1980 = {0xc8df3700, 0x00000002}
const LARGE_INTEGER | Magic10000 = {0xe219652c, 0xd1b71758}
const LARGE_INTEGER | Magic10000000 = {0xe57a42bd, 0xd6bf94d5}
const LARGE_INTEGER | Magic86400000 = {0xfa67b90e, 0xc6d750eb}

## Define Documentation

#define Convert100nsToMilliseconds | ( | LARGE_INTEGER |  | ) |

Value:

    (                         \
        RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 )       \
        )

Definition at line 178 of file time.c.

#define Convert100nsToSeconds | ( | LARGE_INTEGER |  | ) |

Value:

    (                              \
        RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000000, SHIFT10000000 ) \
        )

Definition at line 186 of file time.c.

#define ConvertDaysToMilliseconds | ( | DAYS |  | ) |

Value:

    (                          \
        Int32x32To64( (DAYS), 86400000 )                               \
        )

Definition at line 198 of file time.c.

Referenced by DaysAndFractionToTime(), and TimeToDaysAndFraction().

#define ConvertMillisecondsTo100ns | ( | MILLISECONDS |  | ) |

Value:

    (                 \
        RtlExtendedIntegerMultiply( (MILLISECONDS), 10000 )            \
        )

Definition at line 182 of file time.c.

#define ConvertMillisecondsToDays | ( | LARGE_INTEGER |  | ) |

Value:

    (                          \
        RtlExtendedMagicDivide( (LARGE_INTEGER), Magic86400000, SHIFT86400000 ) \
        )

Definition at line 194 of file time.c.

#define ConvertSecondsTo100ns | ( | SECONDS |  | ) |

Value:

    (                           \
        RtlExtendedIntegerMultiply( (SECONDS), 10000000 )              \
        )

Definition at line 190 of file time.c.

#define ElapsedYearsToDays | ( | YEARS |  | ) |

Value:

    (            \
        ((YEARS) * 365) + NumberOfLeapYears(YEARS) \
        )

Definition at line 310 of file time.c.

#define IsLeapYear | ( | YEARS |  | ) |

Value:

    (                        \
        (((YEARS) % 400 == 0) ||                       \
         ((YEARS) % 100 != 0) && ((YEARS) % 4 == 0)) ? \
            TRUE                                       \
        :                                              \
            FALSE                                      \
        )

Definition at line 324 of file time.c.

#define MaxDaysInMonth | ( | YEAR,
|  | MONTH |  | ) |

Value:

    (                                      \
        IsLeapYear(YEAR) ?                                                    \
            LeapYearDaysPrecedingMonth[(MONTH) + 1] -                         \
                                        LeapYearDaysPrecedingMonth[(MONTH)]   \
        :                                                                     \
            NormalYearDaysPrecedingMonth[(MONTH) + 1] -                       \
                                        NormalYearDaysPrecedingMonth[(MONTH)] \
        )

Definition at line 344 of file time.c.

#define NumberOfLeapYears | ( | YEARS |  | ) |

Value:

    (                    \
        ((YEARS) / 4) - ((YEARS) / 100) + ((YEARS) / 400) \
        )

Definition at line 295 of file time.c.

#define SHIFT10000 13

| Definition at line 165 of file time.c.

#define SHIFT10000000 23

| Definition at line 168 of file time.c.

#define SHIFT86400000 26

| Definition at line 171 of file time.c.

#define WEEKDAY_OF_1601 1

| Definition at line 138 of file time.c.

## Function Documentation

VOID DaysAndFractionToTime | ( | IN ULONG | ElapsedDays,
|  | IN ULONG | Milliseconds,
|  | OUT PLARGE_INTEGER | Time
| ) |

Definition at line 443 of file time.c.

References ConvertDaysToMilliseconds, ConvertMillisecondsTo100ns, and Time.

Referenced by RtlTimeFieldsToTime().

    00451                    :
    00452
    00453     This routine converts an input elapsed day count and partial time
    00454     in milliseconds to a 64-bit time value.
    00455
    00456 Arguments:
    00457
    00458     ElapsedDays - Supplies the number of elapsed days
    00459
    00460     Milliseconds - Supplies the number of milliseconds in the partial day
    00461
    00462     Time - Receives the output time to value
    00463
    00464 Return Value:
    00465
    00466     None
    00467
    00468 --*/
    00469
    00470 {
    00471     LARGE_INTEGER Temp;
    00472     LARGE_INTEGER Temp2;
    00473
    00474     //
    00475     //  Calculate the exact number of milliseconds in the elapsed days.
    00476     //
    00477
    00478     Temp.QuadPart = ConvertDaysToMilliseconds( ElapsedDays );
    00479
    00480     //
    00481     //  Convert milliseconds to a large integer
    00482     //
    00483
    00484     Temp2.LowPart = Milliseconds;
    00485     Temp2.HighPart = 0;
    00486
    00487     //
    00488     //  add milliseconds to the whole day milliseconds
    00489     //
    00490
    00491     Temp.QuadPart = Temp.QuadPart + Temp2.QuadPart;
    00492
    00493     //
    00494     //  Finally convert the milliseconds to 100ns resolution
    00495     //
    00496
    00497     *(PLARGE_INTEGER)Time = ConvertMillisecondsTo100ns( Temp );
    00498
    00499     //
    00500     //  and return to our caller
    00501     //
    00502
    00503     return;
    00504 }

ULONG ElapsedDaysToYears | ( | IN ULONG | ElapsedDays | ) |

Definition at line 208 of file time.c.

    00214                    :
    00215
    00216     This routine computes the number of total years contained in the indicated
    00217     number of elapsed days.  The computation is to first compute the number of
    00218     400 years and subtract that it, then do the 100 years and subtract that out,
    00219     then do the number of 4 years and subtract that out.  Then what we have left
    00220     is the number of days with in a normalized 4 year block.  Normalized being that
    00221     the first three years are not leap years.
    00222
    00223 Arguments:
    00224
    00225     ElapsedDays - Supplies the number of days to use
    00226
    00227 Return Value:
    00228
    00229     ULONG - Returns the number of whole years contained within the input number
    00230         of days.
    00231
    00232 --*/
    00233
    00234 {
    00235     ULONG NumberOf400s;
    00236     ULONG NumberOf100s;
    00237     ULONG NumberOf4s;
    00238     ULONG Years;
    00239
    00240     //
    00241     //  A 400 year time block is 365*400 + 400/4 - 400/100 + 400/400 = 146097 days
    00242     //  long.  So we simply compute the number of whole 400 year block and the
    00243     //  the number days contained in those whole blocks, and subtract if from the
    00244     //  elapsed day total
    00245     //
    00246
    00247     NumberOf400s = ElapsedDays / 146097;
    00248     ElapsedDays -= NumberOf400s * 146097;
    00249
    00250     //
    00251     //  A 100 year time block is 365*100 + 100/4 - 100/100 = 36524 days long.
    00252     //  The computation for the number of 100 year blocks is biased by 3/4 days per
    00253     //  100 years to account for the extra leap day thrown in on the last year
    00254     //  of each 400 year block.
    00255     //
    00256
    00257     NumberOf100s = (ElapsedDays * 100 + 75) / 3652425;
    00258     ElapsedDays -= NumberOf100s * 36524;
    00259
    00260     //
    00261     //  A 4 year time block is 365*4 + 4/4 = 1461 days long.
    00262     //
    00263
    00264     NumberOf4s = ElapsedDays / 1461;
    00265     ElapsedDays -= NumberOf4s * 1461;
    00266
    00267     //
    00268     //  Now the number of whole years is the number of 400 year blocks times 400,
    00269     //  100 year blocks time 100, 4 year blocks times 4, and the number of elapsed
    00270     //  whole years, taking into account the 3/4 day per year needed to handle the
    00271     //  leap year.
    00272     //
    00273
    00274     Years = (NumberOf400s * 400) +
    00275             (NumberOf100s * 100) +
    00276             (NumberOf4s * 4) +
    00277             (ElapsedDays * 100 + 75) / 36525;
    00278
    00279     return Years;
    00280 }

BOOLEAN RtlCutoverTimeToSystemTime | ( | PTIME_FIELDS | CutoverTime,
|  | PLARGE_INTEGER | SystemTime,
|  | PLARGE_INTEGER | CurrentSystemTime,
|  | BOOLEAN | ThisYear
| ) |

Definition at line 655 of file time.c.

References FALSE, RtlTimeFieldsToTime(), RtlTimeToTimeFields(), and TRUE.

    00661 {
    00662     TIME_FIELDS CurrentTimeFields;
    00663
    00664     //
    00665     // Get the current system time
    00666     //
    00667
    00668     RtlTimeToTimeFields(CurrentSystemTime,&CurrentTimeFields);
    00669
    00670     //
    00671     // check for absolute time field. If the year is specified,
    00672     // the the time is an abosulte time
    00673     //
    00674
    00675     if ( CutoverTime->Year ) {
    00676
    00677         //
    00678         // Convert this to a time value and make sure it
    00679         // is greater than the current system time
    00680         //
    00681
    00682         if ( !RtlTimeFieldsToTime(CutoverTime,SystemTime) ) {
    00683             return FALSE;
    00684             }
    00685
    00686         if (SystemTime->QuadPart < CurrentSystemTime->QuadPart) {
    00687             return FALSE;
    00688             }
    00689         return TRUE;
    00690         }
    00691     else {
    00692
    00693         TIME_FIELDS WorkingTimeField;
    00694         TIME_FIELDS ScratchTimeField;
    00695         LARGE_INTEGER ScratchTime;
    00696         CSHORT BestWeekdayDate;
    00697         CSHORT WorkingWeekdayNumber;
    00698         CSHORT TargetWeekdayNumber;
    00699         CSHORT TargetYear;
    00700         CSHORT TargetMonth;
    00701         CSHORT TargetWeekday;     // range [0..6] == [Sunday..Saturday]
    00702         BOOLEAN MonthMatches;
    00703         //
    00704         // The time is an day in the month style time
    00705         //
    00706         // the convention is the Day is 1-5 specifying 1st, 2nd... Last
    00707         // day within the month. The day is WeekDay.
    00708         //
    00709
    00710         //
    00711         // Compute the target month and year
    00712         //
    00713
    00714         TargetWeekdayNumber = CutoverTime->Day;
    00715         if ( TargetWeekdayNumber > 5 || TargetWeekdayNumber == 0 ) {
    00716             return FALSE;
    00717             }
    00718         TargetWeekday = CutoverTime->Weekday;
    00719         TargetMonth = CutoverTime->Month;
    00720         MonthMatches = FALSE;
    00721         if ( !ThisYear ) {
    00722             if ( TargetMonth < CurrentTimeFields.Month ) {
    00723                 TargetYear = CurrentTimeFields.Year + 1;
    00724                 }
    00725             else if ( TargetMonth > CurrentTimeFields.Month ) {
    00726                 TargetYear = CurrentTimeFields.Year;
    00727                 }
    00728             else {
    00729                 TargetYear = CurrentTimeFields.Year;
    00730                 MonthMatches = TRUE;
    00731                 }
    00732             }
    00733         else {
    00734             TargetYear = CurrentTimeFields.Year;
    00735             }
    00736 try_next_year:
    00737         BestWeekdayDate = 0;
    00738
    00739         WorkingTimeField.Year = TargetYear;
    00740         WorkingTimeField.Month = TargetMonth;
    00741         WorkingTimeField.Day = 1;
    00742         WorkingTimeField.Hour = CutoverTime->Hour;
    00743         WorkingTimeField.Minute = CutoverTime->Minute;
    00744         WorkingTimeField.Second = CutoverTime->Second;
    00745         WorkingTimeField.Milliseconds = CutoverTime->Milliseconds;
    00746         WorkingTimeField.Weekday = 0;
    00747
    00748         //
    00749         // Convert to time and then back to time fields so we can determine
    00750         // the weekday of day 1 on the month
    00751         //
    00752
    00753         if ( !RtlTimeFieldsToTime(&WorkingTimeField,&ScratchTime) ) {
    00754             return FALSE;
    00755             }
    00756         RtlTimeToTimeFields(&ScratchTime,&ScratchTimeField);
    00757
    00758         //
    00759         // Compute bias to target weekday
    00760         //
    00761         if ( ScratchTimeField.Weekday > TargetWeekday ) {
    00762             WorkingTimeField.Day += (7-(ScratchTimeField.Weekday - TargetWeekday));
    00763             }
    00764         else if ( ScratchTimeField.Weekday < TargetWeekday ) {
    00765             WorkingTimeField.Day += (TargetWeekday - ScratchTimeField.Weekday);
    00766             }
    00767
    00768         //
    00769         // We are now at the first weekday that matches our target weekday
    00770         //
    00771
    00772         BestWeekdayDate = WorkingTimeField.Day;
    00773         WorkingWeekdayNumber = 1;
    00774
    00775         //
    00776         // Keep going one week at a time until we either pass the
    00777         // target weekday, or we match exactly
    00778         //
    00779
    00780         while ( WorkingWeekdayNumber < TargetWeekdayNumber ) {
    00781             WorkingTimeField.Day += 7;
    00782             if ( !RtlTimeFieldsToTime(&WorkingTimeField,&ScratchTime) ) {
    00783                 break;
    00784                 }
    00785             RtlTimeToTimeFields(&ScratchTime,&ScratchTimeField);
    00786             WorkingWeekdayNumber++;
    00787             BestWeekdayDate = ScratchTimeField.Day;
    00788             }
    00789         WorkingTimeField.Day = BestWeekdayDate;
    00790
    00791         //
    00792         // If the months match, and the date is less than the current
    00793         // date, then be have to go to next year.
    00794         //
    00795
    00796         if ( !RtlTimeFieldsToTime(&WorkingTimeField,&ScratchTime) ) {
    00797             return FALSE;
    00798             }
    00799         if ( MonthMatches ) {
    00800             if ( WorkingTimeField.Day < CurrentTimeFields.Day ) {
    00801                 MonthMatches = FALSE;
    00802                 TargetYear++;
    00803                 goto try_next_year;
    00804                 }
    00805             if ( WorkingTimeField.Day == CurrentTimeFields.Day ) {
    00806
    00807                 if (ScratchTime.QuadPart < CurrentSystemTime->QuadPart) {
    00808                     MonthMatches = FALSE;
    00809                     TargetYear++;
    00810                     goto try_next_year;
    00811                     }
    00812                 }
    00813             }
    00814         *SystemTime = ScratchTime;
    00815
    00816         return TRUE;
    00817         }
    00818 }

NTSTATUS RtlLocalTimeToSystemTime | ( | IN PLARGE_INTEGER | LocalTime,
|  | OUT PLARGE_INTEGER | SystemTime
| ) |

Definition at line 1306 of file time.c.

References NT_SUCCESS, NTSTATUS(), NULL, and Status.

    01310 {
    01311
    01312     NTSTATUS Status;
    01313     SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
    01314
    01315     Status = ZwQuerySystemInformation(
    01316                 SystemTimeOfDayInformation,
    01317                 &TimeOfDay,
    01318                 sizeof(TimeOfDay),
    01319                 NULL
    01320                 );
    01321     if ( !NT_SUCCESS(Status) ) {
    01322         return Status;
    01323         }
    01324
    01325     //
    01326     // SystemTime = LocalTime + TimeZoneBias
    01327     //
    01328
    01329     SystemTime->QuadPart = LocalTime->QuadPart + TimeOfDay.TimeZoneBias.QuadPart;
    01330
    01331     return STATUS_SUCCESS;
    01332 }

VOID RtlSecondsSince1970ToTime | ( | IN ULONG | ElapsedSeconds,
|  | OUT PLARGE_INTEGER | Time
| ) |

Definition at line 1223 of file time.c.

References ConvertSecondsTo100ns, SecondsToStartOf1970, and Time.

Referenced by main().

    01230                    :
    01231
    01232     This routine converts the seconds since the start of 1970 to an
    01233     NT Time value
    01234
    01235 Arguments:
    01236
    01237     ElapsedSeconds - Supplies the number of seconds from the start of 1970
    01238         to convert from
    01239
    01240     Time - Receives the converted Time value
    01241
    01242 Return Value:
    01243
    01244     None
    01245
    01246 --*/
    01247
    01248 {
    01249     LARGE_INTEGER Seconds;
    01250
    01251     //
    01252     //  Move elapsed seconds to a large integer
    01253     //
    01254
    01255     Seconds.LowPart = ElapsedSeconds;
    01256     Seconds.HighPart = 0;
    01257
    01258     //
    01259     //  Convert number of seconds from 1970 to number of seconds from 1601
    01260     //
    01261
    01262     Seconds.QuadPart = Seconds.QuadPart + SecondsToStartOf1970.QuadPart;
    01263
    01264     //
    01265     //  Convert seconds to 100ns resolution
    01266     //
    01267
    01268     *(PLARGE_INTEGER)Time = ConvertSecondsTo100ns( Seconds );
    01269
    01270     //
    01271     //  return to our caller
    01272     //
    01273
    01274     return;
    01275 }

VOID RtlSecondsSince1980ToTime | ( | IN ULONG | ElapsedSeconds,
|  | OUT PLARGE_INTEGER | Time
| ) |

Definition at line 1098 of file time.c.

References ConvertSecondsTo100ns, SecondsToStartOf1980, and Time.

Referenced by main().

    01105                    :
    01106
    01107     This routine converts the seconds since the start of 1980 to an
    01108     NT Time value.
    01109
    01110 Arguments:
    01111
    01112     ElapsedSeconds - Supplies the number of seconds from the start of 1980
    01113         to convert from
    01114
    01115     Time - Receives the converted Time value
    01116
    01117 Return Value:
    01118
    01119     None
    01120
    01121 --*/
    01122
    01123 {
    01124     LARGE_INTEGER Seconds;
    01125
    01126     //
    01127     //  Move elapsed seconds to a large integer
    01128     //
    01129
    01130     Seconds.LowPart = ElapsedSeconds;
    01131     Seconds.HighPart = 0;
    01132
    01133     //
    01134     //  convert number of seconds from 1980 to number of seconds from 1601
    01135     //
    01136
    01137     Seconds.QuadPart = Seconds.QuadPart + SecondsToStartOf1980.QuadPart;
    01138
    01139     //
    01140     //  Convert seconds to 100ns resolution
    01141     //
    01142
    01143     *(PLARGE_INTEGER)Time = ConvertSecondsTo100ns( Seconds );
    01144
    01145     //
    01146     //  and return to our caller
    01147     //
    01148
    01149     return;
    01150 }

NTSTATUS RtlSystemTimeToLocalTime | ( | IN PLARGE_INTEGER | SystemTime,
|  | OUT PLARGE_INTEGER | LocalTime
| ) |

Definition at line 1278 of file time.c.

References NT_SUCCESS, NTSTATUS(), NULL, and Status.

    01282 {
    01283     NTSTATUS Status;
    01284     SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
    01285
    01286     Status = ZwQuerySystemInformation(
    01287                 SystemTimeOfDayInformation,
    01288                 &TimeOfDay,
    01289                 sizeof(TimeOfDay),
    01290                 NULL
    01291                 );
    01292     if ( !NT_SUCCESS(Status) ) {
    01293         return Status;
    01294         }
    01295
    01296     //
    01297     // LocalTime = SystemTime - TimeZoneBias
    01298     //
    01299
    01300     LocalTime->QuadPart = SystemTime->QuadPart - TimeOfDay.TimeZoneBias.QuadPart;
    01301
    01302     return STATUS_SUCCESS;
    01303 }

BOOLEAN RtlTimeFieldsToTime | ( | IN PTIME_FIELDS | TimeFields,
|  | OUT PLARGE_INTEGER | Time
| ) |

Definition at line 822 of file time.c.

References DaysAndFractionToTime(), ElapsedYearsToDays, FALSE, IsLeapYear, LeapYearDaysPrecedingMonth, MaxDaysInMonth, NormalYearDaysPrecedingMonth, Time, TimeFields, and TRUE.

Referenced by main(), RtlCutoverTimeToSystemTime(), SeMakeAnonymousLogonToken(), SeMakeSystemToken(), TestTokenInitialize(), and UdfConvertUdfTimeToNtTime().

    00829                    :
    00830
    00831     This routine converts an input Time Field variable to a 64-bit NT time
    00832     value.  It ignores the WeekDay of the time field.
    00833
    00834 Arguments:
    00835
    00836     TimeFields - Supplies the time field record to use
    00837
    00838     Time - Receives the NT Time corresponding to TimeFields
    00839
    00840 Return Value:
    00841
    00842     BOOLEAN - TRUE if the Time Fields is well formed and within the
    00843         range of time expressible by LARGE_INTEGER and FALSE otherwise.
    00844
    00845 --*/
    00846
    00847 {
    00848     ULONG Year;
    00849     ULONG Month;
    00850     ULONG Day;
    00851     ULONG Hour;
    00852     ULONG Minute;
    00853     ULONG Second;
    00854     ULONG Milliseconds;
    00855
    00856     ULONG ElapsedDays;
    00857     ULONG ElapsedMilliseconds;
    00858
    00859     //
    00860     //  Load the time field elements into local variables.  This should
    00861     //  ensure that the compiler will only load the input elements
    00862     //  once, even if there are alias problems.  It will also make
    00863     //  everything (except the year) zero based.  We cannot zero base the
    00864     //  year because then we can't recognize cases where we're given a year
    00865     //  before 1601.
    00866     //
    00867
    00868     Year         = TimeFields->Year;
    00869     Month        = TimeFields->Month - 1;
    00870     Day          = TimeFields->Day - 1;
    00871     Hour         = TimeFields->Hour;
    00872     Minute       = TimeFields->Minute;
    00873     Second       = TimeFields->Second;
    00874     Milliseconds = TimeFields->Milliseconds;
    00875
    00876     //
    00877     //  Check that the time field input variable contains
    00878     //  proper values.
    00879     //
    00880
    00881     if ((TimeFields->Month < 1)                      ||
    00882         (TimeFields->Day < 1)                        ||
    00883         (Year < 1601)                                ||
    00884         (Month > 11)                                 ||
    00885         ((CSHORT)Day >= MaxDaysInMonth(Year, Month)) ||
    00886         (Hour > 23)                                  ||
    00887         (Minute > 59)                                ||
    00888         (Second > 59)                                ||
    00889         (Milliseconds > 999)) {
    00890
    00891         return FALSE;
    00892
    00893     }
    00894
    00895     //
    00896     //  Compute the total number of elapsed days represented by the
    00897     //  input time field variable
    00898     //
    00899
    00900     ElapsedDays = ElapsedYearsToDays( Year - 1601 );
    00901
    00902     if (IsLeapYear( Year - 1600 )) {
    00903
    00904         ElapsedDays += LeapYearDaysPrecedingMonth[ Month ];
    00905
    00906     } else {
    00907
    00908         ElapsedDays += NormalYearDaysPrecedingMonth[ Month ];
    00909
    00910     }
    00911
    00912     ElapsedDays += Day;
    00913
    00914     //
    00915     //  Now compute the total number of milliseconds in the fractional
    00916     //  part of the day
    00917     //
    00918
    00919     ElapsedMilliseconds = (((Hour*60) + Minute)*60 + Second)*1000 + Milliseconds;
    00920
    00921     //
    00922     //  Given the elapsed days and milliseconds we can now build
    00923     //  the output time variable
    00924     //
    00925
    00926     DaysAndFractionToTime( ElapsedDays, ElapsedMilliseconds, Time );
    00927
    00928     //
    00929     //  And return to our caller
    00930     //
    00931
    00932     return TRUE;
    00933 }

VOID RtlTimeToElapsedTimeFields | ( | IN PLARGE_INTEGER | Time,
|  | OUT PTIME_FIELDS | TimeFields
| ) |

Definition at line 937 of file time.c.

References Time, TimeFields, and TimeToDaysAndFraction().

    00944                    :
    00945
    00946     This routine converts an input 64-bit LARGE_INTEGER variable to its corresponding
    00947     time field record.  The input time is the elapsed time (difference
    00948     between to times).  It will tell the caller the number of days, hour,
    00949     minute, second, and milliseconds that the elapsed time represents.
    00950
    00951 Arguments:
    00952
    00953     Time - Supplies the time value to interpret
    00954
    00955     TimeFields - Receives a value corresponding to Time
    00956
    00957 Return Value:
    00958
    00959     None
    00960
    00961 --*/
    00962
    00963 {
    00964     ULONG Days;
    00965     ULONG Hours;
    00966     ULONG Minutes;
    00967     ULONG Seconds;
    00968     ULONG Milliseconds;
    00969
    00970     //
    00971     //  First divide the input time 64 bit time variable into
    00972     //  the number of whole days and part days (in milliseconds)
    00973     //
    00974
    00975     TimeToDaysAndFraction( Time, &Days, &Milliseconds );
    00976
    00977     //
    00978     //  Now we need to compute the elapsed hour, minute, second, milliseconds
    00979     //  from the millisecond variable.  This variable currently contains
    00980     //  the number of milliseconds in our input time variable that did not
    00981     //  fit into a whole day.  To compute the hour, minute, second part
    00982     //  we will actually do the arithmetic backwards computing milliseconds
    00983     //  seconds, minutes, and then hours.  We start by computing the
    00984     //  number of whole seconds left in the day, and then computing
    00985     //  the millisecond remainder.
    00986     //
    00987
    00988     Seconds = Milliseconds / 1000;
    00989     Milliseconds = Milliseconds % 1000;
    00990
    00991     //
    00992     //  Now we compute the number of whole minutes left in the day
    00993     //  and the number of remainder seconds
    00994     //
    00995
    00996     Minutes = Seconds / 60;
    00997     Seconds = Seconds % 60;
    00998
    00999     //
    01000     //  Now compute the number of whole hours left in the day
    01001     //  and the number of remainder minutes
    01002     //
    01003
    01004     Hours = Minutes / 60;
    01005     Minutes = Minutes % 60;
    01006
    01007     //
    01008     //  As our final step we put everything into the time fields
    01009     //  output variable
    01010     //
    01011
    01012     TimeFields->Year         = 0;
    01013     TimeFields->Month        = 0;
    01014     TimeFields->Day          = (CSHORT)Days;
    01015     TimeFields->Hour         = (CSHORT)Hours;
    01016     TimeFields->Minute       = (CSHORT)Minutes;
    01017     TimeFields->Second       = (CSHORT)Seconds;
    01018     TimeFields->Milliseconds = (CSHORT)Milliseconds;
    01019
    01020     //
    01021     //  and return to our caller
    01022     //
    01023
    01024     return;
    01025 }

BOOLEAN RtlTimeToSecondsSince1970 | ( | IN PLARGE_INTEGER | Time,
|  | OUT PULONG | ElapsedSeconds
| ) |

Definition at line 1154 of file time.c.

References Convert100nsToSeconds, FALSE, SecondsToStartOf1970, Time, and TRUE.

Referenced by main().

    01161                    :
    01162
    01163     This routine converts an input 64-bit NT Time variable to the
    01164     number of seconds since the start of 1970.  The NT time must be
    01165     within the range 1970 to around 2105.
    01166
    01167 Arguments:
    01168
    01169     Time - Supplies the Time to convert from
    01170
    01171     ElapsedSeconds - Receives the number of seconds since the start of 1970
    01172         denoted by Time
    01173
    01174 Return Value:
    01175
    01176     BOOLEAN - TRUE if the input time is within the range expressible by
    01177         ElapsedSeconds and FALSE otherwise
    01178
    01179 --*/
    01180
    01181 {
    01182     LARGE_INTEGER Seconds;
    01183
    01184     //
    01185     //  First convert time to seconds since 1601
    01186     //
    01187
    01188     Seconds = Convert100nsToSeconds( *(PLARGE_INTEGER)Time );
    01189
    01190     //
    01191     //  Then subtract the number of seconds from 1601 to 1970.
    01192     //
    01193
    01194     Seconds.QuadPart = Seconds.QuadPart - SecondsToStartOf1970.QuadPart;
    01195
    01196     //
    01197     //  If the results is negative then the date was before 1970 or if
    01198     //  the results is greater than a ulong then its too far in the
    01199     //  future so we return FALSE
    01200     //
    01201
    01202     if (Seconds.HighPart != 0) {
    01203
    01204         return FALSE;
    01205
    01206     }
    01207
    01208     //
    01209     //  Otherwise we have the answer
    01210     //
    01211
    01212     *ElapsedSeconds = Seconds.LowPart;
    01213
    01214     //
    01215     //  And return to our caller
    01216     //
    01217
    01218     return TRUE;
    01219 }

BOOLEAN RtlTimeToSecondsSince1980 | ( | IN PLARGE_INTEGER | Time,
|  | OUT PULONG | ElapsedSeconds
| ) |

Definition at line 1029 of file time.c.

References Convert100nsToSeconds, FALSE, SecondsToStartOf1980, Time, and TRUE.

Referenced by main().

    01036                    :
    01037
    01038     This routine converts an input 64-bit NT Time variable to the
    01039     number of seconds since the start of 1980.  The NT time must be
    01040     within the range 1980 to around 2115.
    01041
    01042 Arguments:
    01043
    01044     Time - Supplies the Time to convert from
    01045
    01046     ElapsedSeconds - Receives the number of seconds since the start of 1980
    01047         denoted by Time
    01048
    01049 Return Value:
    01050
    01051     BOOLEAN - TRUE if the input Time is within a range expressible by
    01052         ElapsedSeconds and FALSE otherwise
    01053
    01054 --*/
    01055
    01056 {
    01057     LARGE_INTEGER Seconds;
    01058
    01059     //
    01060     //  First convert time to seconds since 1601
    01061     //
    01062
    01063     Seconds = Convert100nsToSeconds( *(PLARGE_INTEGER)Time );
    01064
    01065     //
    01066     //  Then subtract the number of seconds from 1601 to 1980.
    01067     //
    01068
    01069     Seconds.QuadPart = Seconds.QuadPart - SecondsToStartOf1980.QuadPart;
    01070
    01071     //
    01072     //  If the results is negative then the date was before 1980 or if
    01073     //  the results is greater than a ulong then its too far in the
    01074     //  future so we return FALSE
    01075     //
    01076
    01077     if (Seconds.HighPart != 0) {
    01078
    01079         return FALSE;
    01080
    01081     }
    01082
    01083     //
    01084     //  Otherwise we have the answer
    01085     //
    01086
    01087     *ElapsedSeconds = Seconds.LowPart;
    01088
    01089     //
    01090     //  And return to our caller
    01091     //
    01092
    01093     return TRUE;
    01094 }

VOID RtlTimeToTimeFields | ( | IN PLARGE_INTEGER | Time,
|  | OUT PTIME_FIELDS | TimeFields
| ) |

Definition at line 508 of file time.c.

References ElapsedDaysToYears, ElapsedYearsToDays, IsLeapYear, LeapYearDaysPrecedingMonth, LeapYearDayToMonth, NormalYearDaysPrecedingMonth, NormalYearDayToMonth, Time, TimeFields, TimeToDaysAndFraction(), and WEEKDAY_OF_1601.

Referenced by ExGetNextWakeTime(), IopCopyBootLogRegistryToFile(), KeSetSystemTime(), main(), MiInitializeSpecialPoolCriteria(), and RtlCutoverTimeToSystemTime().

    00515                    :
    00516
    00517     This routine converts an input 64-bit LARGE_INTEGER variable to its corresponding
    00518     time field record.  It will tell the caller the year, month, day, hour,
    00519     minute, second, millisecond, and weekday corresponding to the input time
    00520     variable.
    00521
    00522 Arguments:
    00523
    00524     Time - Supplies the time value to interpret
    00525
    00526     TimeFields - Receives a value corresponding to Time
    00527
    00528 Return Value:
    00529
    00530     None
    00531
    00532 --*/
    00533
    00534 {
    00535     ULONG Years;
    00536     ULONG Month;
    00537     ULONG Days;
    00538
    00539     ULONG Hours;
    00540     ULONG Minutes;
    00541     ULONG Seconds;
    00542     ULONG Milliseconds;
    00543
    00544     //
    00545     //  First divide the input time 64 bit time variable into
    00546     //  the number of whole days and part days (in milliseconds)
    00547     //
    00548
    00549     TimeToDaysAndFraction( Time, &Days, &Milliseconds );
    00550
    00551     //
    00552     //  Compute which weekday it is and save it away now in the output
    00553     //  variable.  We add the weekday of the base day to bias our computation
    00554     //  which means that if one day has elapsed then we the weekday we want
    00555     //  is the Jan 2nd, 1601.
    00556     //
    00557
    00558     TimeFields->Weekday = (CSHORT)((Days + WEEKDAY_OF_1601) % 7);
    00559
    00560     //
    00561     //  Calculate the number of whole years contained in the elapsed days
    00562     //  For example if Days = 500 then Years = 1
    00563     //
    00564
    00565     Years = ElapsedDaysToYears( Days );
    00566
    00567     //
    00568     //  And subtract the number of whole years from our elapsed days
    00569     //  For example if Days = 500, Years = 1, and the new days is equal
    00570     //  to 500 - 365 (normal year).
    00571     //
    00572
    00573     Days = Days - ElapsedYearsToDays( Years );
    00574
    00575     //
    00576     //  Now test whether the year we are working on (i.e., The year
    00577     //  after the total number of elapsed years) is a leap year
    00578     //  or not.
    00579     //
    00580
    00581     if (IsLeapYear( Years + 1 )) {
    00582
    00583         //
    00584         //  The current year is a leap year, so figure out what month
    00585         //  it is, and then subtract the number of days preceding the
    00586         //  month from the days to figure out what day of the month it is
    00587         //
    00588
    00589         Month = LeapYearDayToMonth[Days];
    00590         Days = Days - LeapYearDaysPrecedingMonth[Month];
    00591
    00592     } else {
    00593
    00594         //
    00595         //  The current year is a normal year, so figure out the month
    00596         //  and days as described above for the leap year case
    00597         //
    00598
    00599         Month = NormalYearDayToMonth[Days];
    00600         Days = Days - NormalYearDaysPrecedingMonth[Month];
    00601
    00602     }
    00603
    00604     //
    00605     //  Now we need to compute the elapsed hour, minute, second, milliseconds
    00606     //  from the millisecond variable.  This variable currently contains
    00607     //  the number of milliseconds in our input time variable that did not
    00608     //  fit into a whole day.  To compute the hour, minute, second part
    00609     //  we will actually do the arithmetic backwards computing milliseconds
    00610     //  seconds, minutes, and then hours.  We start by computing the
    00611     //  number of whole seconds left in the day, and then computing
    00612     //  the millisecond remainder.
    00613     //
    00614
    00615     Seconds = Milliseconds / 1000;
    00616     Milliseconds = Milliseconds % 1000;
    00617
    00618     //
    00619     //  Now we compute the number of whole minutes left in the day
    00620     //  and the number of remainder seconds
    00621     //
    00622
    00623     Minutes = Seconds / 60;
    00624     Seconds = Seconds % 60;
    00625
    00626     //
    00627     //  Now compute the number of whole hours left in the day
    00628     //  and the number of remainder minutes
    00629     //
    00630
    00631     Hours = Minutes / 60;
    00632     Minutes = Minutes % 60;
    00633
    00634     //
    00635     //  As our final step we put everything into the time fields
    00636     //  output variable
    00637     //
    00638
    00639     TimeFields->Year         = (CSHORT)(Years + 1601);
    00640     TimeFields->Month        = (CSHORT)(Month + 1);
    00641     TimeFields->Day          = (CSHORT)(Days + 1);
    00642     TimeFields->Hour         = (CSHORT)Hours;
    00643     TimeFields->Minute       = (CSHORT)Minutes;
    00644     TimeFields->Second       = (CSHORT)Seconds;
    00645     TimeFields->Milliseconds = (CSHORT)Milliseconds;
    00646
    00647     //
    00648     //  and return to our caller
    00649     //
    00650
    00651     return;
    00652 }

VOID TimeToDaysAndFraction | ( | IN PLARGE_INTEGER | Time,
|  | OUT PULONG | ElapsedDays,
|  | OUT PULONG | Milliseconds
| ) | `[static]`

Definition at line 361 of file time.c.

References Convert100nsToMilliseconds, ConvertDaysToMilliseconds, ConvertMillisecondsToDays, and Time.

Referenced by RtlTimeToElapsedTimeFields(), and RtlTimeToTimeFields().

    00369                    :
    00370
    00371     This routine converts an input 64-bit time value to the number
    00372     of total elapsed days and the number of milliseconds in the
    00373     partial day.
    00374
    00375 Arguments:
    00376
    00377     Time - Supplies the input time to convert from
    00378
    00379     ElapsedDays - Receives the number of elapsed days
    00380
    00381     Milliseconds - Receives the number of milliseconds in the partial day
    00382
    00383 Return Value:
    00384
    00385     None
    00386
    00387 --*/
    00388
    00389 {
    00390     LARGE_INTEGER TotalMilliseconds;
    00391     LARGE_INTEGER Temp;
    00392
    00393     //
    00394     //  Convert the input time to total milliseconds
    00395     //
    00396
    00397     TotalMilliseconds = Convert100nsToMilliseconds( *(PLARGE_INTEGER)Time );
    00398
    00399     //
    00400     //  Convert milliseconds to total days
    00401     //
    00402
    00403     Temp = ConvertMillisecondsToDays( TotalMilliseconds );
    00404
    00405     //
    00406     //  Set the elapsed days from temp, we've divided it enough so that
    00407     //  the high part must be zero.
    00408     //
    00409
    00410     *ElapsedDays = Temp.LowPart;
    00411
    00412     //
    00413     //  Calculate the exact number of milliseconds in the elapsed days
    00414     //  and subtract that from the total milliseconds to figure out
    00415     //  the number of milliseconds left in the partial day
    00416     //
    00417
    00418     Temp.QuadPart = ConvertDaysToMilliseconds( *ElapsedDays );
    00419
    00420     Temp.QuadPart = TotalMilliseconds.QuadPart - Temp.QuadPart;
    00421
    00422     //
    00423     //  Set the fraction part from temp, the total number of milliseconds in
    00424     //  a day guarantees that the high part must be zero.
    00425     //
    00426
    00427     *Milliseconds = Temp.LowPart;
    00428
    00429     //
    00430     //  And return to our caller
    00431     //
    00432
    00433     return;
    00434 }

## Variable Documentation

CONST CSHORT LeapYearDaysPrecedingMonth[13]

Initial value:

     {
        0,
        31,
        31+29,
        31+29+31,
        31+29+31+30,
        31+29+31+30+31,
        31+29+31+30+31+30,
        31+29+31+30+31+30+31,
        31+29+31+30+31+30+31+31,
        31+29+31+30+31+30+31+31+30,
        31+29+31+30+31+30+31+31+30+31,
        31+29+31+30+31+30+31+31+30+31+30,
        31+29+31+30+31+30+31+31+30+31+30+31}

Definition at line 98 of file time.c.

Referenced by RtlTimeFieldsToTime(), and RtlTimeToTimeFields().

CONST UCHAR LeapYearDayToMonth[366]

Initial value:

     {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11}

Definition at line 62 of file time.c.

Referenced by RtlTimeToTimeFields().

const LARGE_INTEGER Magic10000 = {0xe219652c, 0xd1b71758}

| Definition at line 164 of file time.c.

const LARGE_INTEGER Magic10000000 = {0xe57a42bd, 0xd6bf94d5}

| Definition at line 167 of file time.c.

const LARGE_INTEGER Magic86400000 = {0xfa67b90e, 0xc6d750eb}

| Definition at line 170 of file time.c.

CONST CSHORT NormalYearDaysPrecedingMonth[13]

Initial value:

     {
        0,
        31,
        31+28,
        31+28+31,
        31+28+31+30,
        31+28+31+30+31,
        31+28+31+30+31+30,
        31+28+31+30+31+30+31,
        31+28+31+30+31+30+31+31,
        31+28+31+30+31+30+31+31+30,
        31+28+31+30+31+30+31+31+30+31,
        31+28+31+30+31+30+31+31+30+31+30,
        31+28+31+30+31+30+31+31+30+31+30+31}

Definition at line 113 of file time.c.

Referenced by RtlTimeFieldsToTime(), and RtlTimeToTimeFields().

CONST UCHAR NormalYearDayToMonth[365]

Initial value:

     {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
        10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
        11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11}

Definition at line 76 of file time.c.

Referenced by RtlTimeToTimeFields().

const LARGE_INTEGER SecondsToStartOf1970 = {0xb6109100, 0x00000002}

| Definition at line 149 of file time.c. Referenced by RtlSecondsSince1970ToTime(), and RtlTimeToSecondsSince1970().

const LARGE_INTEGER SecondsToStartOf1980 = {0xc8df3700, 0x00000002}

| Definition at line 151 of file time.c. Referenced by RtlSecondsSince1980ToTime(), and RtlTimeToSecondsSince1980().