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.

155 lines
4.3 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. *
  14. *******************************************************************************/
  15. #include <cruntime.h>
  16. #include <time.h>
  17. #include <ctime.h>
  18. #include <stddef.h>
  19. #include <internal.h>
  20. #include <mtdll.h>
  21. #ifdef _MT
  22. #include <malloc.h>
  23. #include <stddef.h>
  24. #endif
  25. #include <dbgint.h>
  26. static struct tm tb = { 0 }; /* time block */
  27. /***
  28. *struct tm *_gmtime64(timp) - convert *timp to a structure (UTC)
  29. *
  30. *Purpose:
  31. * Converts the calendar time value, in internal 64-bit format to
  32. * broken-down time (tm structure) with the corresponding UTC time.
  33. *
  34. *Entry:
  35. * const __time64_t *timp - pointer to time_t value to convert
  36. *
  37. *Exit:
  38. * returns pointer to filled-in tm structure.
  39. * returns NULL if *timp < 0
  40. *
  41. *Exceptions:
  42. *
  43. *******************************************************************************/
  44. struct tm * __cdecl _gmtime64 (
  45. const __time64_t *timp
  46. )
  47. {
  48. __time64_t caltim = *timp; /* calendar time to convert */
  49. int islpyr = 0; /* is-current-year-a-leap-year flag */
  50. int tmptim;
  51. int *mdays; /* pointer to days or lpdays */
  52. #ifdef _MT
  53. struct tm *ptb; /* will point to gmtime buffer */
  54. _ptiddata ptd = _getptd();
  55. #else
  56. struct tm *ptb = &tb;
  57. #endif
  58. if ( (caltim < 0) || (caltim > _MAX__TIME64_T) )
  59. return(NULL);
  60. #ifdef _MT
  61. /* Use per thread buffer area (malloc space, if necessary) */
  62. if ( (ptd->_gmtimebuf != NULL) || ((ptd->_gmtimebuf =
  63. _malloc_crt(sizeof(struct tm))) != NULL) )
  64. ptb = ptd->_gmtimebuf;
  65. else
  66. ptb = &tb; /* malloc error: use static buffer */
  67. #endif
  68. /*
  69. * Determine the years since 1900. Start by ignoring leap years.
  70. */
  71. tmptim = (int)(caltim / _YEAR_SEC) + 70;
  72. caltim -= ((__time64_t)(tmptim - 70) * _YEAR_SEC);
  73. /*
  74. * Correct for elapsed leap years
  75. */
  76. caltim -= ((__time64_t)_ELAPSED_LEAP_YEARS(tmptim) * _DAY_SEC);
  77. /*
  78. * If we have underflowed the __time64_t range (i.e., if caltim < 0),
  79. * back up one year, adjusting the correction if necessary.
  80. */
  81. if ( caltim < 0 ) {
  82. caltim += (__time64_t)_YEAR_SEC;
  83. tmptim--;
  84. if ( _IS_LEAP_YEAR(tmptim) ) {
  85. caltim += _DAY_SEC;
  86. islpyr++;
  87. }
  88. }
  89. else
  90. if ( _IS_LEAP_YEAR(tmptim) )
  91. islpyr++;
  92. /*
  93. * tmptim now holds the value for tm_year. caltim now holds the
  94. * number of elapsed seconds since the beginning of that year.
  95. */
  96. ptb->tm_year = tmptim;
  97. /*
  98. * Determine days since January 1 (0 - 365). This is the tm_yday value.
  99. * Leave caltim with number of elapsed seconds in that day.
  100. */
  101. ptb->tm_yday = (int)(caltim / _DAY_SEC);
  102. caltim -= (__time64_t)(ptb->tm_yday) * _DAY_SEC;
  103. /*
  104. * Determine months since January (0 - 11) and day of month (1 - 31)
  105. */
  106. if ( islpyr )
  107. mdays = _lpdays;
  108. else
  109. mdays = _days;
  110. for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ;
  111. ptb->tm_mon = --tmptim;
  112. ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
  113. /*
  114. * Determine days since Sunday (0 - 6)
  115. */
  116. ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7;
  117. /*
  118. * Determine hours since midnight (0 - 23), minutes after the hour
  119. * (0 - 59), and seconds after the minute (0 - 59).
  120. */
  121. ptb->tm_hour = (int)(caltim / 3600);
  122. caltim -= (__time64_t)ptb->tm_hour * 3600L;
  123. ptb->tm_min = (int)(caltim / 60);
  124. ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
  125. ptb->tm_isdst = 0;
  126. return( (struct tm *)ptb );
  127. }