Windows NT 4.0 source code leak
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.

185 lines
4.7 KiB

4 years ago
  1. /***
  2. *gmtime.c - breaks down a time value into GMT date/time info
  3. *
  4. * Copyright (c) 1985-1993, 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. *
  31. *******************************************************************************/
  32. #include <cruntime.h>
  33. #include <time.h>
  34. #include <ctime.h>
  35. #include <stddef.h>
  36. #include <internal.h>
  37. #include <os2dll.h>
  38. #ifdef MTHREAD
  39. #include <malloc.h>
  40. #include <stddef.h>
  41. #endif
  42. static struct tm tb = { 0 }; /* time block */
  43. /***
  44. *struct tm *gmtime(timp) - convert *timp to a structure (UTC)
  45. *
  46. *Purpose:
  47. * Converts the calendar time value, in internal format (time_t), to
  48. * broken-down time (tm structure) with the corresponding UTC time.
  49. *
  50. *Entry:
  51. * const time_t *timp - pointer to time_t value to convert
  52. *
  53. *Exit:
  54. * returns pointer to filled-in tm structure.
  55. * returns NULL if *timp < 0L
  56. *
  57. *Exceptions:
  58. *
  59. *******************************************************************************/
  60. struct tm * _CRTAPI1 gmtime (
  61. const time_t *timp
  62. )
  63. {
  64. long caltim = *timp; /* calendar time to convert */
  65. int islpyr = 0; /* is-current-year-a-leap-year flag */
  66. REG1 int tmptim;
  67. REG3 int *mdays; /* pointer to days or lpdays */
  68. #ifdef MTHREAD
  69. REG2 struct tm *ptb; /* will point to gmtime buffer */
  70. _ptiddata ptd = _getptd();
  71. #else
  72. REG2 struct tm *ptb = &tb;
  73. #endif
  74. if ( caltim < 0L )
  75. return(NULL);
  76. #ifdef MTHREAD
  77. /* Use per thread buffer area (malloc space, if necessary) */
  78. if ( (ptd->_gmtimebuf != NULL) || ((ptd->_gmtimebuf =
  79. malloc(sizeof(struct tm))) != NULL) )
  80. ptb = ptd->_gmtimebuf;
  81. else
  82. ptb = &tb; /* malloc error: use static buffer */
  83. #endif
  84. /*
  85. * Determine years since 1970. First, identify the four-year interval
  86. * since this makes handling leap-years easy (note that 2000 IS a
  87. * leap year and 2100 is out-of-range).
  88. */
  89. tmptim = (int)(caltim / _FOUR_YEAR_SEC);
  90. caltim -= ((long)tmptim * _FOUR_YEAR_SEC);
  91. /*
  92. * Determine which year of the interval
  93. */
  94. tmptim = (tmptim * 4) + 70; /* 1970, 1974, 1978,...,etc. */
  95. if ( caltim >= _YEAR_SEC ) {
  96. tmptim++; /* 1971, 1975, 1979,...,etc. */
  97. caltim -= _YEAR_SEC;
  98. if ( caltim >= _YEAR_SEC ) {
  99. tmptim++; /* 1972, 1976, 1980,...,etc. */
  100. caltim -= _YEAR_SEC;
  101. /*
  102. * Note, it takes 366 days-worth of seconds to get past a leap
  103. * year.
  104. */
  105. if ( caltim >= (_YEAR_SEC + _DAY_SEC) ) {
  106. tmptim++; /* 1973, 1977, 1981,...,etc. */
  107. caltim -= (_YEAR_SEC + _DAY_SEC);
  108. }
  109. else {
  110. /*
  111. * In a leap year after all, set the flag.
  112. */
  113. islpyr++;
  114. }
  115. }
  116. }
  117. /*
  118. * tmptim now holds the value for tm_year. caltim now holds the
  119. * number of elapsed seconds since the beginning of that year.
  120. */
  121. ptb->tm_year = tmptim;
  122. /*
  123. * Determine days since January 1 (0 - 365). This is the tm_yday value.
  124. * Leave caltim with number of elapsed seconds in that day.
  125. */
  126. ptb->tm_yday = (int)(caltim / _DAY_SEC);
  127. caltim -= (long)(ptb->tm_yday) * _DAY_SEC;
  128. /*
  129. * Determine months since January (0 - 11) and day of month (1 - 31)
  130. */
  131. if ( islpyr )
  132. mdays = _lpdays;
  133. else
  134. mdays = _days;
  135. for ( tmptim = 1 ; mdays[tmptim] < ptb->tm_yday ; tmptim++ ) ;
  136. ptb->tm_mon = --tmptim;
  137. ptb->tm_mday = ptb->tm_yday - mdays[tmptim];
  138. /*
  139. * Determine days since Sunday (0 - 6)
  140. */
  141. ptb->tm_wday = ((int)(*timp / _DAY_SEC) + _BASE_DOW) % 7;
  142. /*
  143. * Determine hours since midnight (0 - 23), minutes after the hour
  144. * (0 - 59), and seconds after the minute (0 - 59).
  145. */
  146. ptb->tm_hour = (int)(caltim / 3600);
  147. caltim -= (long)ptb->tm_hour * 3600L;
  148. ptb->tm_min = (int)(caltim / 60);
  149. ptb->tm_sec = (int)(caltim - (ptb->tm_min) * 60);
  150. ptb->tm_isdst = 0;
  151. return( (struct tm *)ptb );
  152. }