Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

450 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. stdtimep.h
  5. Abstract:
  6. This module contains definitions and function prototypes which are local to
  7. stdime.c and fmttime.c.
  8. Author:
  9. Rob McKaughan (t-robmc) 17-Jul-1991
  10. Revision History:
  11. --*/
  12. #ifndef _STD_TIME_P_
  13. #define _STD_TIME_P_
  14. //
  15. // These are the magic numbers needed to do our extended division. The
  16. // only numbers we ever need to divide by are
  17. //
  18. // 10,000 = convert 100ns tics to millisecond tics
  19. //
  20. // 10,000,000 = convert 100ns tics to one second tics
  21. //
  22. // 86,400,000 = convert Millisecond tics to one day tics
  23. //
  24. extern LARGE_INTEGER Magic10000;
  25. #define SHIFT10000 13
  26. extern LARGE_INTEGER Magic10000000;
  27. #define SHIFT10000000 23
  28. extern LARGE_INTEGER Magic86400000;
  29. #define SHIFT86400000 26
  30. //
  31. // To make the code more readable we'll also define some macros to
  32. // do the actual division for use
  33. //
  34. #define Convert100nsToMilliseconds(LARGE_INTEGER) ( \
  35. RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 ) \
  36. )
  37. #define ConvertMillisecondsTo100ns(MILLISECONDS) ( \
  38. RtlExtendedIntegerMultiply( (MILLISECONDS), 10000 ) \
  39. )
  40. #define Convert100nsToSeconds(LARGE_INTEGER) ( \
  41. RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000000, SHIFT10000000 ) \
  42. )
  43. #define ConvertSecondsTo100ns(SECONDS) ( \
  44. RtlExtendedIntegerMultiply( (SECONDS), 10000000L ) \
  45. )
  46. #define ConvertMillisecondsToDays(LARGE_INTEGER) ( \
  47. RtlExtendedMagicDivide( (LARGE_INTEGER), Magic86400000, SHIFT86400000 ) \
  48. )
  49. ///////////////////////////////////////////////////////////////////////////////
  50. // //
  51. // Macros for Time Differentials and Time Revisions //
  52. // //
  53. ///////////////////////////////////////////////////////////////////////////////
  54. //
  55. // The following define the minimum and maximum possible values for the Time
  56. // Differential Factor as defined by ISO 4031-1978.
  57. //
  58. #define MAX_STDTIME_TDF (780)
  59. #define MIN_STDTIME_TDF (-720)
  60. //
  61. // The revision of this design (will be inserted in the revision field of any
  62. // STANDARD_TIMEs created by this revision).
  63. //
  64. #define STDTIME_REVISION (4)
  65. //
  66. // The number of bits we need to shift to get to and from a revision in a
  67. // StdTime.TdfAndRevision field.
  68. //
  69. #define STDTIME_REVISION_SHIFT 12
  70. //
  71. // USHORT
  72. // ShiftStandardTimeRevision(
  73. // IN USHORT Rev
  74. // )
  75. // Description:
  76. // This routine shifts the given revision number to its proper place for
  77. // storing in a STANDARD_TIME.TdfAndRevision field.
  78. //
  79. #define ShiftStandardTimeRevision(Rev) \
  80. ((USHORT) ((Rev) << STDTIME_REVISION_SHIFT))
  81. //
  82. // The pre-shifted value of the current revision
  83. //
  84. #define SHIFTED_STDTIME_REVISION (ShiftStandardTimeRevision(STDTIME_REVISION))
  85. //
  86. // The bit mask used to mask a STANDARD_TIME.TdfAndRevision field to retrieve
  87. // the Tdf value.
  88. //
  89. #define TDF_MASK ((USHORT) 0x0fff)
  90. //
  91. // USHORT
  92. // MaskStandardTimeTdf(
  93. // IN USHORT Tdf
  94. // )
  95. // Description:
  96. // This routine masks the given tdf field with TDF_MASK and returns the
  97. // result.
  98. //
  99. // BUG: Byte order dependant
  100. //
  101. #define MaskStandardTimeTdf(Tdf) ((USHORT) ((Tdf) & TDF_MASK))
  102. //
  103. // SHORT
  104. // GetStandardTimeTdf(
  105. // IN STANDARD_TIME
  106. // )
  107. // Description:
  108. // This routine gets the Time Differential Factor from a tdf field and
  109. // makes any adjustments necessary to preserve the sign of the TDF.
  110. // The resulting TDF is returned.
  111. //
  112. // Since the TDF is stored as a signed 12 bit int, it's sign bit is the
  113. // bit 0x0800. To make it a 16 bit negative, we subtract 0x1000 from the
  114. // bottome 12 bits of the TdfAndRevision field.
  115. //
  116. // BUG: Byte order dependant
  117. //
  118. #define GetStandardTimeTdf(StdTime) \
  119. ((SHORT) \
  120. (((StdTime)->TdfAndRevision) & 0x0800) \
  121. ? (MaskStandardTimeTdf((StdTime)->TdfAndRevision) - 0x1000) \
  122. : MaskStandardTimeTdf((StdTime)->TdfAndRevision) \
  123. )
  124. //
  125. // USHORT
  126. // GetStandardTimeRev(
  127. // IN USHORT Tdf
  128. // )
  129. // Description:
  130. // This routine gets the revision number from a tdf field and returns it
  131. // shifted back down to its place as a SHORT.
  132. //
  133. #define GetStandardTimeRev(StdTime) \
  134. ((USHORT) (((StdTime)->TdfAndRevision) >> STDTIME_REVISION_SHIFT))
  135. ///////////////////////////////////////////////////////////////////////////////
  136. // //
  137. // Tests for absolute and delta times //
  138. // //
  139. ///////////////////////////////////////////////////////////////////////////////
  140. //
  141. // BOOLEAN
  142. // IsPositive(
  143. // IN LARGE_INTEGER Time
  144. // )
  145. // Returns:
  146. // TRUE - if the time in Time is positive.
  147. // FALSE - if Time is negative.
  148. //
  149. #define IsPositive(Time) \
  150. ( ((Time).HighPart > 0) || (((Time).HighPart = 0) & ((Time).LowPart > 0)) )
  151. //
  152. // BOOLEAN
  153. // IsAbsoluteTime(
  154. // IN PSTANDARDTIME Time
  155. // )
  156. // Returns:
  157. // TRUE - if the given time is an absolute time
  158. // FALSE - If the given time is not an absolute time
  159. //
  160. #define IsAbsoluteTime(Time) \
  161. ( IsPositive(Time->SimpleTime) )
  162. //
  163. // BOOLEAN
  164. // IsDeltaTime(
  165. // IN PSTANDARDTIME Time
  166. // )
  167. // Returns:
  168. // TRUE - if the given time is a delta time
  169. // FALSE - If the given time is not a delta time
  170. //
  171. #define IsDeltaTime(Time) \
  172. ( !IsAbsoluteTime(Time) )
  173. //
  174. // BOOLEAN
  175. // GreaterThanTime(
  176. // IN PLARGE_INTEGER Time1,
  177. // IN PLARGE_INTEGER Time2
  178. // )
  179. // Returns:
  180. // TRUE - If Time1 is greater (older) than Time2
  181. // FALSE - If not
  182. //
  183. // BUG: Byte order dependant
  184. // BUG: Only works on absolute times
  185. //
  186. #define GreaterThanTime(Time1, Time2) \
  187. ( \
  188. ((Time1).HighPart > (Time2).HighPart) \
  189. || \
  190. ( \
  191. ((Time1).HighPart == (Time2).HighPart) \
  192. && \
  193. ((Time1).LowPart > (Time2).LowPart) \
  194. ) \
  195. )
  196. //
  197. // BOOLEAN
  198. // GreaterThanStandardTime(
  199. // IN PSTANDARD_TIME Time1,
  200. // IN PSTANDARD_TIME Time2
  201. // )
  202. // Returns:
  203. // TRUE - If Time1 is greater (older) than Time2
  204. // FALSE - If not
  205. //
  206. #define GreaterThanStdTime(Time1, Time2) \
  207. GreaterThanTime((Time1).SimpleTime, (Time2).SimpleTime)
  208. //////////////////////////////////////////////////////////////////////////////
  209. // /
  210. // The following definitions and declarations are some important constants /
  211. // used in the time conversion routines /
  212. // /
  213. //////////////////////////////////////////////////////////////////////////////
  214. //
  215. // This is the week day that January 1st, 1601 fell on (a Monday)
  216. //
  217. #define WEEKDAY_OF_1601 1
  218. //
  219. // These are known constants used to convert 1970 and 1980 times to 1601
  220. // times. They are the number of seconds from the 1601 base to the start
  221. // of 1970 and the start of 1980. The number of seconds from 1601 to
  222. // 1970 is 369 years worth, or (369 * 365) + 89 leap days = 134774 days, or
  223. // 134774 * 864000 seconds, which is equal to the large integer defined
  224. // below. The number of seconds from 1601 to 1980 is 379 years worth, or etc.
  225. //
  226. // These are declared in time.c
  227. //
  228. extern const LARGE_INTEGER SecondsToStartOf1970;
  229. extern const LARGE_INTEGER SecondsToStartOf1980;
  230. //
  231. // ULONG
  232. // ElapsedDaysToYears (
  233. // IN ULONG ElapsedDays
  234. // );
  235. //
  236. // To be completely true to the Gregorian calendar the equation to
  237. // go from days to years is really
  238. //
  239. // ElapsedDays / 365.2425
  240. //
  241. // But because we are doing the computation in ulong integer arithmetic
  242. // and the LARGE_INTEGER variable limits the number of expressible days to around
  243. // 11,000,000 we use the following computation
  244. //
  245. // (ElapsedDays * 128 + 127) / (365.2425 * 128)
  246. //
  247. // which will be off from the Gregorian calendar in about 150,000 years
  248. // but that doesn't really matter because LARGE_INTEGER can only express around
  249. // 30,000 years
  250. //
  251. #define ElapsedDaysToYears(DAYS) ( \
  252. ((DAYS) * 128 + 127) / 46751 \
  253. )
  254. //
  255. // ULONG
  256. // NumberOfLeapYears (
  257. // IN ULONG ElapsedYears
  258. // );
  259. //
  260. // The number of leap years is simply the number of years divided by 4
  261. // minus years divided by 100 plus years divided by 400. This says
  262. // that every four years is a leap year except centuries, and the
  263. // exception to the exception is the quadricenturies
  264. //
  265. #define NumberOfLeapYears(YEARS) ( \
  266. ((YEARS) / 4) - ((YEARS) / 100) + ((YEARS) / 400) \
  267. )
  268. //
  269. // ULONG
  270. // ElapsedYearsToDays (
  271. // IN ULONG ElapsedYears
  272. // );
  273. //
  274. // The number of days contained in elapsed years is simply the number
  275. // of years times 365 (because every year has at least 365 days) plus
  276. // the number of leap years there are (i.e., the number of 366 days years)
  277. //
  278. #define ElapsedYearsToDays(YEARS) ( \
  279. ((YEARS) * 365) + NumberOfLeapYears(YEARS) \
  280. )
  281. //
  282. // BOOLEAN
  283. // IsLeapYear (
  284. // IN ULONG ElapsedYears
  285. // );
  286. //
  287. // If it is an even 400 or a non century leapyear then the
  288. // answer is true otherwise it's false
  289. //
  290. #define IsLeapYear(YEARS) ( \
  291. (((YEARS) % 400 == 0) || \
  292. ((YEARS) % 100 != 0) && ((YEARS) % 4 == 0)) ? \
  293. TRUE \
  294. : \
  295. FALSE \
  296. )
  297. //
  298. // ULONG
  299. // MaxDaysInMonth (
  300. // IN ULONG Year,
  301. // IN ULONG Month
  302. // );
  303. //
  304. // The maximum number of days in a month depend on the year and month.
  305. // It is the difference between the days to the month and the days
  306. // to the following month
  307. //
  308. #define MaxDaysInMonth(YEAR,MONTH) ( \
  309. IsLeapYear(YEAR) ? \
  310. LeapYearDaysPrecedingMonth[(MONTH) + 1] - \
  311. LeapYearDaysPrecedingMonth[(MONTH)] \
  312. : \
  313. NormalYearDaysPrecedingMonth[(MONTH) + 1] - \
  314. NormalYearDaysPrecedingMonth[(MONTH)] \
  315. )
  316. //
  317. // Local utlity function prototypes
  318. //
  319. VOID
  320. RtlpConvert48To64(
  321. IN PSTDTIME_ERROR num48,
  322. OUT LARGE_INTEGER *num64
  323. );
  324. NTSTATUS
  325. RtlpConvert64To48(
  326. IN LARGE_INTEGER num64,
  327. OUT PSTDTIME_ERROR num48
  328. );
  329. LARGE_INTEGER
  330. RtlpTimeToLargeInt(
  331. IN LARGE_INTEGER Time
  332. );
  333. LARGE_INTEGER
  334. RtlpLargeIntToTime(
  335. IN LARGE_INTEGER Int
  336. );
  337. NTSTATUS
  338. RtlpAdd48Int(
  339. IN PSTDTIME_ERROR First48,
  340. IN PSTDTIME_ERROR Second48,
  341. IN PSTDTIME_ERROR Result48
  342. );
  343. NTSTATUS
  344. RtlpAddTime(
  345. IN LARGE_INTEGER Time1,
  346. IN LARGE_INTEGER Time2,
  347. OUT PLARGE_INTEGER Result
  348. );
  349. NTSTATUS
  350. RtlpSubtractTime(
  351. IN LARGE_INTEGER Time1,
  352. IN LARGE_INTEGER Time2,
  353. OUT PLARGE_INTEGER Result
  354. );
  355. LARGE_INTEGER
  356. RtlpAbsTime(
  357. IN LARGE_INTEGER Time
  358. );
  359. #endif //_STD_TIME_P_