/* * @implemented */ VOID NTAPI RtlTimeToTimeFields(IN PLARGE_INTEGER Time, OUT PTIME_FIELDS TimeFields) { const UCHAR *Months; ULONG SecondsInDay, CurYear; ULONG LeapYear, CurMonth; ULONG Days; ULONGLONG IntTime = Time->QuadPart; /* Extract millisecond from time and convert time into seconds */ TimeFields->Milliseconds = (CSHORT)((IntTime % TICKSPERSEC) / TICKSPERMSEC); IntTime = IntTime / TICKSPERSEC; /* Split the time into days and seconds within the day */ Days = (ULONG)(IntTime / SECSPERDAY); SecondsInDay = IntTime % SECSPERDAY; /* Compute time of day */ TimeFields->Hour = (CSHORT)(SecondsInDay / SECSPERHOUR); SecondsInDay = SecondsInDay % SECSPERHOUR; TimeFields->Minute = (CSHORT)(SecondsInDay / SECSPERMIN); TimeFields->Second = (CSHORT)(SecondsInDay % SECSPERMIN); /* Compute day of week */ TimeFields->Weekday = (CSHORT)((EPOCHWEEKDAY + Days) % DAYSPERWEEK); /* Compute year */ CurYear = EPOCHYEAR; CurYear += Days / DAYSPERLEAPYEAR; Days -= DaysSinceEpoch(CurYear); while (TRUE) { LeapYear = IsLeapYear(CurYear); if (Days < YearLengths[LeapYear]) { break; } CurYear++; Days = Days - YearLengths[LeapYear]; } TimeFields->Year = (CSHORT)CurYear; /* Compute month of year */ LeapYear = IsLeapYear(CurYear); Months = MonthLengths[LeapYear]; for (CurMonth = 0; Days >= Months[CurMonth]; CurMonth++) { Days = Days - Months[CurMonth]; } TimeFields->Month = (CSHORT)(CurMonth + 1); TimeFields->Day = (CSHORT)(Days + 1); }
// derived from ECMA 262 15.9 void TimestampColumn::MillisecondsFromDate(SQL_SS_TIMESTAMPOFFSET_STRUCT const& timeStruct) { double ms = DaysSinceEpoch(timeStruct.year, timeStruct.month, timeStruct.day); ms *= MS_PER_DAY; // add in the hour, day minute, second and millisecond ms += timeStruct.hour * MS_PER_HOUR + timeStruct.minute * MS_PER_MINUTE + timeStruct.second * MS_PER_SECOND; ms += timeStruct.fraction / NANOSECONDS_PER_MS; // fraction is in nanoseconds // handle timezone adjustment to UTC ms -= timeStruct.timezone_hour * MS_PER_HOUR; ms -= timeStruct.timezone_minute * MS_PER_MINUTE; milliseconds = ms; nanoseconds_delta = timeStruct.fraction % NANOSECONDS_PER_MS; }
/* * compute ecliptic longitude of sun (in radians) * (after duffett-smith, section 47) */ static double sun_ecliptic_longitude(time_t ssue) /* seconds since unix epoch */ { double D, N; double M_sun, E; double v; D = DaysSinceEpoch(ssue); N = RadsPerDay * D; M_sun = mean_sun(D); E = solve_keplers_equation(M_sun); v = 2 * atan(sqrt((1 + Eccentricity) / (1 - Eccentricity)) * tan(E / 2)); return (v + OmegaBar_g); }
/* * compute ecliptic longitude of sun (in radians) * (after duffett-smith, section 47) */ static double sun_ecliptic_longitude(time_t ssue) //time_t ssue; /* seconds since unix epoch */ { double D, N; double M_sun, E; double v; D = DaysSinceEpoch(ssue); N = RadsPerDay * D; N = fmod(N, TWOPI); if (N < 0) N += TWOPI; M_sun = N + Epsilon_g - OmegaBar_g; if (M_sun < 0) M_sun += TWOPI; E = solve_keplers_equation(M_sun); v = 2 * atan(sqrt((1+Eccentricity)/(1-Eccentricity)) * tan(E/2)); return (v + OmegaBar_g); }
/* * @implemented */ BOOLEAN NTAPI RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, OUT PLARGE_INTEGER Time) { ULONG CurMonth; TIME_FIELDS IntTimeFields; RtlCopyMemory(&IntTimeFields, TimeFields, sizeof(TIME_FIELDS)); if (TimeFields->Milliseconds < 0 || TimeFields->Milliseconds > 999 || TimeFields->Second < 0 || TimeFields->Second > 59 || TimeFields->Minute < 0 || TimeFields->Minute > 59 || TimeFields->Hour < 0 || TimeFields->Hour > 23 || TimeFields->Month < 1 || TimeFields->Month > 12 || TimeFields->Day < 1 || TimeFields->Day > MonthLengths[IsLeapYear(TimeFields->Year)][TimeFields->Month - 1] || TimeFields->Year < 1601) { return FALSE; } /* Compute the time */ Time->QuadPart = DaysSinceEpoch(IntTimeFields.Year); for (CurMonth = 1; CurMonth < IntTimeFields.Month; CurMonth++) { Time->QuadPart += MonthLengths[IsLeapYear(IntTimeFields.Year)][CurMonth - 1]; } Time->QuadPart += IntTimeFields.Day - 1; Time->QuadPart *= SECSPERDAY; Time->QuadPart += IntTimeFields.Hour * SECSPERHOUR + IntTimeFields.Minute * SECSPERMIN + IntTimeFields.Second; Time->QuadPart *= TICKSPERSEC; Time->QuadPart += IntTimeFields.Milliseconds * TICKSPERMSEC; return TRUE; }
/* * given a particular time (expressed in seconds since the unix * epoch), compute position on the earth (lat, lon) such that the * moon is directly overhead. * * Based on duffett-smith **2nd ed** section 61; combines some steps * into single expressions to reduce the number of extra variables. */ void moon_position(time_t ssue, double *lat, double *lon) /* time_t ssue; seconds since unix epoch */ /* double *lat; (return) latitude in ra */ /* double *lon; (return) longitude in ra */ { double lambda, beta; double D, L, Ms, Mm, N, Ev, Ae, Ec, alpha, delta; D = DaysSinceEpoch(ssue); lambda = sun_ecliptic_longitude(ssue); Ms = mean_sun(D); L = fmod(D / SideralMonth, 1.0) * TWOPI + MoonMeanLongitude; Normalize(L); Mm = L - DegsToRads(0.1114041 * D) - MoonMeanLongitudePerigee; Normalize(Mm); N = MoonMeanLongitudeNode - DegsToRads(0.0529539 * D); Normalize(N); Ev = DegsToRads(1.2739) * sin(2.0 * (L - lambda) - Mm); Ae = DegsToRads(0.1858) * sin(Ms); Mm += Ev - Ae - DegsToRads(0.37) * sin(Ms); Ec = DegsToRads(6.2886) * sin(Mm); L += Ev + Ec - Ae + DegsToRads(0.214) * sin(2.0 * Mm); L += DegsToRads(0.6583) * sin(2.0 * (L - lambda)); N -= DegsToRads(0.16) * sin(Ms); L -= N; lambda = (fabs(cos(L)) < 1e-12) ? (N + sin(L) * cos(MoonInclination) * PI / 2) : (N + atan2(sin(L) * cos(MoonInclination), cos(L))); Normalize(lambda); beta = asin(sin(L) * sin(MoonInclination)); ecliptic_to_equatorial(lambda, beta, &alpha, &delta); alpha -= (TWOPI / 24) * GST(ssue); Normalize(alpha); *lon = alpha; *lat = delta; }