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.

190 lines
6.0 KiB

  1. /***
  2. *gmtime.c - breaks down a time value into GMT date/time info
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines gmtime() - breaks the clock value down into GMT time/date
  8. * information; return pointer to structure with the data.
  9. *
  10. *Revision History:
  11. * 01-??-84 RLB Module created
  12. * 05-??-84 DCW Split off from rest off ctime routines.
  13. * 02-18-87 JCR For MS C, gmtime now returns NULL for out of range
  14. * time/date. (This is for ANSI compatibility.)
  15. * 04-10-87 JCR Changed long declaration to time_t and added const
  16. * 05-21-87 SKS Declare "struct tm tb" as NEAR data
  17. * 11-10-87 SKS Removed IBMC20 switch
  18. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  19. * 05-24-88 PHG Merge DLL and regular versions
  20. * 06-06-89 JCR 386 mthread support
  21. * 11-06-89 KRS Add (unsigned) to handle years 2040-2099 correctly
  22. * 03-20-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
  23. * <cruntime.h>, removed #include <register.h> and
  24. * fixed the copyright. Also, cleaned up the formatting
  25. * a bit.
  26. * 10-04-90 GJF New-style function declarator.
  27. * 07-17-91 GJF Multi-thread support for Win32 [_WIN32_].
  28. * 02-17-93 GJF Changed for new _getptd().
  29. * 03-24-93 GJF Propagated changes from 16-bit tree.
  30. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  31. * 09-06-94 CFW Replace MTHREAD with _MT.
  32. * 01-10-95 CFW Debug CRT allocs.
  33. * 02-07-98 GJF Changes for Win64: replaced long with time_t.
  34. *
  35. *******************************************************************************/
  36. #include <cruntime.h>
  37. #include <time.h>
  38. #include <ctime.h>
  39. #include <stddef.h>
  40. #include <internal.h>
  41. #include <mtdll.h>
  42. #ifdef _MT
  43. #include <malloc.h>
  44. #include <stddef.h>
  45. #endif
  46. #include <dbgint.h>
  47. static struct tm tb = { 0 }; /* time block */
  48. /***
  49. *struct tm *gmtime(timp) - convert *timp to a structure (UTC)
  50. *
  51. *Purpose:
  52. * Converts the calendar time value, in internal format (time_t), to
  53. * broken-down time (tm structure) with the corresponding UTC time.
  54. *
  55. *Entry:
  56. * const time_t *timp - pointer to time_t value to convert
  57. *
  58. *Exit:
  59. * returns pointer to filled-in tm structure.
  60. * returns NULL if *timp < 0L
  61. *
  62. *Exceptions:
  63. *
  64. *******************************************************************************/
  65. struct tm * __cdecl gmtime (
  66. const time_t *timp
  67. )
  68. {
  69. time_t caltim = *timp; /* calendar time to convert */
  70. int islpyr = 0; /* is-current-year-a-leap-year flag */
  71. REG1 int tmptim;
  72. REG3 int *mdays; /* pointer to days or lpdays */
  73. #ifdef _MT
  74. REG2 struct tm *ptb; /* will point to gmtime buffer */
  75. _ptiddata ptd = _getptd();
  76. #else
  77. REG2 struct tm *ptb = &tb;
  78. #endif
  79. if ( caltim < 0 )
  80. return(NULL);
  81. #ifdef _MT
  82. /* Use per thread buffer area (malloc space, if necessary) */
  83. if ( (ptd->_gmtimebuf != NULL) || ((ptd->_gmtimebuf =
  84. _malloc_crt(sizeof(struct tm))) != NULL) )
  85. ptb = ptd->_gmtimebuf;
  86. else
  87. ptb = &tb; /* malloc error: use static buffer */
  88. #endif
  89. /*
  90. * Determine years since 1970. First, identify the four-year interval
  91. * since this makes handling leap-years easy (note that 2000 IS a
  92. * leap year and 2100 is out-of-range).
  93. */
  94. tmptim = (int)(caltim / _FOUR_YEAR_SEC);
  95. caltim -= ((time_t)tmptim * _FOUR_YEAR_SEC);
  96. /*
  97. * Determine which year of the interval
  98. */
  99. tmptim = (tmptim * 4) + 70; /* 1970, 1974, 1978,...,etc. */
  100. if ( caltim >= _YEAR_SEC ) {
  101. tmptim++; /* 1971, 1975, 1979,...,etc. */
  102. caltim -= _YEAR_SEC;
  103. if ( caltim >= _YEAR_SEC ) {
  104. tmptim++; /* 1972, 1976, 1980,...,etc. */
  105. caltim -= _YEAR_SEC;
  106. /*
  107. * Note, it takes 366 days-worth of seconds to get past a leap
  108. * year.
  109. */
  110. if ( caltim >= (_YEAR_SEC + _DAY_SEC) ) {
  111. tmptim++; /* 1973, 1977, 1981,...,etc. */
  112. caltim -= (_YEAR_SEC + _DAY_SEC);
  113. }
  114. else {
  115. /*
  116. * In a leap year after all, set the flag.
  117. */
  118. islpyr++;
  119. }
  120. }
  121. }
  122. /*
  123. * tmptim now holds the value for tm_year. caltim now holds the
  124. * number of elapsed seconds since the beginning of that year.
  125. */
  126. ptb->tm_year = tmptim;
  127. /*
  128. * Determine days since January 1 (0 - 365). This is the tm_yday value.
  129. * Leave caltim with number of elapsed seconds in that day.
  130. */
  131. ptb->tm_yday = (int)(caltim / _DAY_SEC);
  132. caltim -= (time_t)(ptb->tm_yday) * _DAY_SEC;
  133. /*
  134. * Determine months since January (0 - 11) and day of month (1 - 31)
  135. */
  136. if ( islpyr )
  137. mdays = _lpdays;
  138. else
  139. mdays = _days;
  140. for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ;
  141. ptb->tm_mon = --tmptim;
  142. ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
  143. /*
  144. * Determine days since Sunday (0 - 6)
  145. */
  146. ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7;
  147. /*
  148. * Determine hours since midnight (0 - 23), minutes after the hour
  149. * (0 - 59), and seconds after the minute (0 - 59).
  150. */
  151. ptb->tm_hour = (int)(caltim / 3600);
  152. caltim -= (time_t)ptb->tm_hour * 3600L;
  153. ptb->tm_min = (int)(caltim / 60);
  154. ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
  155. ptb->tm_isdst = 0;
  156. return( (struct tm *)ptb );
  157. }