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.

235 lines
7.6 KiB

  1. /***
  2. *dtoxtime.c - convert OS local time to time_t
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines __loctotime_t() - convert OS local time to internal format
  8. * (time_t).
  9. *
  10. *Revision History:
  11. * 03-??-84 RLB written
  12. * 11-18-87 SKS change tzset() to __tzset(), change source file name
  13. * make _dtoxtime a near procedure
  14. * 01-26-88 SKS _dtoxtime is no longer a near procedure (for QC)
  15. * 03-20-90 GJF Made calling type _CALLTYPE1, added #include
  16. * <cruntime.h>, removed #include <register.h> and
  17. * fixed the copyright. Also, cleaned up the formatting
  18. * a bit.
  19. * 10-04-90 GJF New-style function declarator.
  20. * 01-21-91 GJF ANSI naming.
  21. * 05-19-92 DJM ifndef for POSIX build.
  22. * 03-30-93 GJF Revised. Old _dtoxtime is replaced by __gmtotime_t,
  23. * which is more useful on Win32.
  24. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  25. * 04-06-93 GJF Rewrote computation to avoid compiler warnings.
  26. * 07-20-93 GJF Replaced __gmtotime_t with function very similar to
  27. * _dostotime_t() in 16-bit C 8.00. The reason for the
  28. * change is that only local time values can be trusted
  29. * on a Win32 platform. System time may be UTC (as
  30. * documented), and is on NT, or may be the same as
  31. * local time, as on Win32S and Win32C
  32. * 02-10-95 GJF Appended Mac version of source file (somewhat cleaned
  33. * up), with appropriate #ifdef-s.
  34. * 09-25-95 GJF Added DST flag to __loctotime_t's arguments. Also,
  35. * use _dstbias instead of assuming a DST bias of -3600.
  36. * 02-07-98 GJF Changes for Win64: replaced long type with time_t
  37. * 10-19-98 GJF Fill in tm_min and tm_sec before calling _isindst
  38. * 05-17-99 PML Remove all Macintosh support.
  39. * 12-10-99 GB Added support for years beyond 2099.
  40. *
  41. *******************************************************************************/
  42. #ifndef _POSIX_
  43. #include <cruntime.h>
  44. #include <time.h>
  45. #include <ctime.h>
  46. #include <internal.h>
  47. /***
  48. *time_t __loctotime_t(yr, mo, dy, hr, mn, sc, dstflag) - converts OS local
  49. * time to internal time format (i.e., a time_t value)
  50. *
  51. *Purpose:
  52. * Converts a local time value, obtained in a broken down format from
  53. * the host OS, to time_t format (i.e., the number elapsed seconds since
  54. * 01-01-70, 00:00:00, UTC).
  55. *
  56. *Entry:
  57. * int yr, mo, dy - date
  58. * int hr, mn, sc - time
  59. * int dstflag - 1 if Daylight Time, 0 if Standard Time, -1 if
  60. * not specified.
  61. *
  62. *Exit:
  63. * Returns calendar time value.
  64. *
  65. *Exceptions:
  66. *
  67. *******************************************************************************/
  68. time_t __cdecl __loctotime_t (
  69. int yr, /* 0 based */
  70. int mo, /* 1 based */
  71. int dy, /* 1 based */
  72. int hr,
  73. int mn,
  74. int sc,
  75. int dstflag )
  76. {
  77. int tmpdays;
  78. time_t tmptim;
  79. struct tm tb;
  80. /*
  81. * Do a quick range check on the year and convert it to a delta
  82. * off of 1900.
  83. */
  84. if ( ((yr -= 1900) < _BASE_YEAR) || (yr > _MAX_YEAR) )
  85. return (time_t)(-1);
  86. /*
  87. * Compute the number of elapsed days in the current year. Note the
  88. * test for a leap year would fail in the year 2100, if this was in
  89. * range (which it isn't).
  90. */
  91. tmpdays = dy + _days[mo - 1];
  92. if ( _IS_LEAP_YEAR(yr) && (mo > 2) )
  93. tmpdays++;
  94. /*
  95. * Compute the number of elapsed seconds since the Epoch. Note the
  96. * computation of elapsed leap years would break down after 2100
  97. * if such values were in range (fortunately, they aren't).
  98. */
  99. tmptim = /* 365 days for each year */
  100. (((time_t)yr - _BASE_YEAR) * 365
  101. /* one day for each elapsed leap year */
  102. + (time_t)_ELAPSED_LEAP_YEARS(yr)
  103. /* number of elapsed days in yr */
  104. + tmpdays)
  105. /* convert to hours and add in hr */
  106. * 24 + hr;
  107. tmptim = /* convert to minutes and add in mn */
  108. (tmptim * 60 + mn)
  109. /* convert to seconds and add in sec */
  110. * 60 + sc;
  111. /*
  112. * Account for time zone.
  113. */
  114. __tzset();
  115. tmptim += _timezone;
  116. /*
  117. * Fill in enough fields of tb for _isindst(), then call it to
  118. * determine DST.
  119. */
  120. tb.tm_yday = tmpdays;
  121. tb.tm_year = yr;
  122. tb.tm_mon = mo - 1;
  123. tb.tm_hour = hr;
  124. tb.tm_min = mn;
  125. tb.tm_sec = sc;
  126. if ( (dstflag == 1) || ((dstflag == -1) && _daylight &&
  127. _isindst(&tb)) )
  128. tmptim += _dstbias;
  129. return(tmptim);
  130. }
  131. #if 0
  132. /*
  133. * THE FOLLOWING FUNCTION WAS DEFINED AND USED (IN PLACE OF THE ONE ABOVE)
  134. * FOR THE CUDA PRODUCT AND THE NT 1.0 SDK. IT WAS REPLACED (BY THE ONE
  135. * ABOVE) BECAUSE NON-NT WIN32 PLATFORMS MAY USE LOCAL TIME FOR SYSTEM TIME,
  136. * RATHER THAN UTC.
  137. */
  138. /***
  139. *time_t __gmtotime_t(yr, mo, dy, hr, mn, sc) - convert broken down time (UTC)
  140. * to time_t
  141. *
  142. *Purpose:
  143. * Converts a broken down UTC (GMT) time to time_t. This is similar to
  144. * _mkgmtime() except there is minimal overflow checking and no updating
  145. * of the input values (i.e., the fields of tm structure).
  146. *
  147. *Entry:
  148. * int yr, mo, dy - date
  149. * int hr, mn, sc - time
  150. *
  151. *Exit:
  152. * returns time_t value
  153. *
  154. *Exceptions:
  155. *
  156. *******************************************************************************/
  157. time_t __cdecl __gmtotime_t (
  158. int yr, /* 0 based */
  159. int mo, /* 1 based */
  160. int dy, /* 1 based */
  161. int hr,
  162. int mn,
  163. int sc
  164. )
  165. {
  166. int tmpdays;
  167. long tmptim;
  168. /*
  169. * Do a quick range check on the year and convert it to a delta
  170. * off of 1900.
  171. */
  172. if ( ((long)(yr -= 1900) < _BASE_YEAR) || ((long)yr > _MAX_YEAR) )
  173. return (time_t)(-1);
  174. /*
  175. * Compute the number of elapsed days in the current year minus
  176. * one. Note the test for leap year and the would fail in the year 2100
  177. * if this was in range (which it isn't).
  178. */
  179. tmpdays = dy + _days[mo - 1];
  180. if ( !(yr & 3) && (mo > 2) )
  181. /*
  182. * in a leap year, after Feb. add one day for elapsed
  183. * Feb 29.
  184. */
  185. tmpdays++;
  186. /*
  187. * Compute the number of elapsed seconds since the Epoch. Note the
  188. * computation of elapsed leap years would break down after 2100
  189. * if such values were in range (fortunately, they aren't).
  190. */
  191. tmptim = /* 365 days for each year */
  192. (((long)yr - _BASE_YEAR) * 365L
  193. /* one day for each elapsed leap year */
  194. + (long)((yr - 1) >> 2) - _LEAP_YEAR_ADJUST
  195. /* number of elapsed days in yr */
  196. + tmpdays)
  197. /* convert to hours and add in hr */
  198. * 24L + hr;
  199. tmptim = /* convert to minutes and add in mn */
  200. (tmptim * 60L + mn)
  201. /* convert to seconds and add in sec */
  202. * 60L + sc;
  203. return (tmptim >= 0) ? (time_t)tmptim : (time_t)(-1);
  204. }
  205. #endif
  206. #endif /* _POSIX_ */