Leaked source code of windows server 2003
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.

167 lines
4.8 KiB

  1. /***
  2. *gmtime64.c - breaks down a time value into GMT date/time info
  3. *
  4. * Copyright (c) 1998-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _gmtime64() - breaks the clock value down into GMT time/date
  8. * information; returns pointer to structure with the data.
  9. *
  10. *Revision History:
  11. * 05-13-98 GJF Created. Adapted from Win64 version of _gmtime64.c.
  12. * 06-12-98 GJF Fixed elapsed years calculation.
  13. * 10-19-01 BWT Return NULL on malloc failure in MT case instead of
  14. * using static buffer.
  15. * 12-11-01 BWT return null if getptd fails instead of exiting program
  16. *
  17. *******************************************************************************/
  18. #include <cruntime.h>
  19. #include <time.h>
  20. #include <ctime.h>
  21. #include <stddef.h>
  22. #include <internal.h>
  23. #include <mtdll.h>
  24. #ifdef _MT
  25. #include <malloc.h>
  26. #include <stddef.h>
  27. #include <errno.h>
  28. #endif
  29. #include <dbgint.h>
  30. #if !defined(_MT)
  31. static struct tm tb = { 0 }; /* time block */
  32. #endif
  33. /***
  34. *struct tm *_gmtime64(timp) - convert *timp to a structure (UTC)
  35. *
  36. *Purpose:
  37. * Converts the calendar time value, in internal 64-bit format to
  38. * broken-down time (tm structure) with the corresponding UTC time.
  39. *
  40. *Entry:
  41. * const __time64_t *timp - pointer to time_t value to convert
  42. *
  43. *Exit:
  44. * returns pointer to filled-in tm structure.
  45. * returns NULL if *timp < 0
  46. *
  47. *Exceptions:
  48. *
  49. *******************************************************************************/
  50. struct tm * __cdecl _gmtime64 (
  51. const __time64_t *timp
  52. )
  53. {
  54. __time64_t caltim = *timp; /* calendar time to convert */
  55. int islpyr = 0; /* is-current-year-a-leap-year flag */
  56. int tmptim;
  57. int *mdays; /* pointer to days or lpdays */
  58. #ifdef _MT
  59. struct tm *ptb; /* will point to gmtime buffer */
  60. _ptiddata ptd = _getptd_noexit();
  61. if (!ptd) {
  62. errno = ENOMEM;
  63. return (NULL);
  64. }
  65. #else
  66. struct tm *ptb = &tb;
  67. #endif
  68. if ( (caltim < 0) || (caltim > _MAX__TIME64_T) )
  69. return(NULL);
  70. #ifdef _MT
  71. /* Use per thread buffer area (malloc space, if necessary) */
  72. if ( (ptd->_gmtimebuf != NULL) || ((ptd->_gmtimebuf =
  73. _malloc_crt(sizeof(struct tm))) != NULL) )
  74. ptb = ptd->_gmtimebuf;
  75. else
  76. {
  77. errno = ENOMEM;
  78. return (NULL);
  79. }
  80. #endif
  81. /*
  82. * Determine the years since 1900. Start by ignoring leap years.
  83. */
  84. tmptim = (int)(caltim / _YEAR_SEC) + 70;
  85. caltim -= ((__time64_t)(tmptim - 70) * _YEAR_SEC);
  86. /*
  87. * Correct for elapsed leap years
  88. */
  89. caltim -= ((__time64_t)_ELAPSED_LEAP_YEARS(tmptim) * _DAY_SEC);
  90. /*
  91. * If we have underflowed the __time64_t range (i.e., if caltim < 0),
  92. * back up one year, adjusting the correction if necessary.
  93. */
  94. if ( caltim < 0 ) {
  95. caltim += (__time64_t)_YEAR_SEC;
  96. tmptim--;
  97. if ( _IS_LEAP_YEAR(tmptim) ) {
  98. caltim += _DAY_SEC;
  99. islpyr++;
  100. }
  101. }
  102. else
  103. if ( _IS_LEAP_YEAR(tmptim) )
  104. islpyr++;
  105. /*
  106. * tmptim now holds the value for tm_year. caltim now holds the
  107. * number of elapsed seconds since the beginning of that year.
  108. */
  109. ptb->tm_year = tmptim;
  110. /*
  111. * Determine days since January 1 (0 - 365). This is the tm_yday value.
  112. * Leave caltim with number of elapsed seconds in that day.
  113. */
  114. ptb->tm_yday = (int)(caltim / _DAY_SEC);
  115. caltim -= (__time64_t)(ptb->tm_yday) * _DAY_SEC;
  116. /*
  117. * Determine months since January (0 - 11) and day of month (1 - 31)
  118. */
  119. if ( islpyr )
  120. mdays = _lpdays;
  121. else
  122. mdays = _days;
  123. for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ;
  124. ptb->tm_mon = --tmptim;
  125. ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
  126. /*
  127. * Determine days since Sunday (0 - 6)
  128. */
  129. ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7;
  130. /*
  131. * Determine hours since midnight (0 - 23), minutes after the hour
  132. * (0 - 59), and seconds after the minute (0 - 59).
  133. */
  134. ptb->tm_hour = (int)(caltim / 3600);
  135. caltim -= (__time64_t)ptb->tm_hour * 3600L;
  136. ptb->tm_min = (int)(caltim / 60);
  137. ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
  138. ptb->tm_isdst = 0;
  139. return( (struct tm *)ptb );
  140. }