tm_conv.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #if 0
  2. #include <time.h>
  3. /* This is a translation from ALGOL in Collected Algorithms of CACM. */
  4. /* Copied from Algorithm 199, Author: Robert G. Tantzen */
  5. void __tm_conv(tmbuf, timep, offset)
  6. struct tm *tmbuf;
  7. time_t *timep;
  8. time_t offset;
  9. {
  10. static int moffset[] =
  11. { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  12. long s;
  13. long j, d, m, y;
  14. offset += *timep;
  15. tmbuf->tm_isdst = 0; /* Someone else can set this */
  16. j = offset / 86400L + 719469;
  17. s = offset % 86400L;
  18. if (s < 0) {
  19. s += 86400L;
  20. j--;
  21. }
  22. tmbuf->tm_sec = s % 60;
  23. tmbuf->tm_min = (s / 60) % 60;
  24. tmbuf->tm_hour = s / 3600;
  25. tmbuf->tm_wday = (j + 2) % 7;
  26. /*
  27. * Julian date converter. Takes a julian date (the number of days since
  28. * some distant epoch or other), and fills tmbuf.
  29. */
  30. y = (4L * j - 1L) / 146097L;
  31. j = 4L * j - 1L - 146097L * y;
  32. d = j / 4L;
  33. j = (4L * d + 3L) / 1461L;
  34. d = 4L * d + 3L - 1461L * j;
  35. d = (d + 4L) / 4L;
  36. m = (5L * d - 3L) / 153L;
  37. d = 5L * d - 3 - 153L * m;
  38. d = (d + 5L) / 5L;
  39. y = 100L * y + j;
  40. if (m < 10)
  41. m += 2;
  42. else {
  43. m -= 10;
  44. ++y;
  45. }
  46. tmbuf->tm_year = y - 1900;
  47. tmbuf->tm_mon = m;
  48. tmbuf->tm_mday = d;
  49. tmbuf->tm_yday = d + moffset[m];
  50. if (m > 1 && ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)))
  51. tmbuf->tm_yday++;
  52. }
  53. #else
  54. /* This is adapted from glibc */
  55. /* Copyright (C) 1991, 1993 Free Software Foundation, Inc */
  56. #define SECS_PER_HOUR 3600L
  57. #define SECS_PER_DAY 86400L
  58. #include <time.h>
  59. static const unsigned short int __mon_lengths[2][12] = {
  60. /* Normal years. */
  61. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  62. /* Leap years. */
  63. {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
  64. };
  65. void __tm_conv(tmbuf, t, offset)
  66. struct tm *tmbuf;
  67. time_t *t;
  68. time_t offset;
  69. {
  70. long days, rem;
  71. register int y;
  72. register const unsigned short int *ip;
  73. days = *t / SECS_PER_DAY;
  74. rem = *t % SECS_PER_DAY;
  75. rem += offset;
  76. while (rem < 0) {
  77. rem += SECS_PER_DAY;
  78. --days;
  79. }
  80. while (rem >= SECS_PER_DAY) {
  81. rem -= SECS_PER_DAY;
  82. ++days;
  83. }
  84. tmbuf->tm_hour = rem / SECS_PER_HOUR;
  85. rem %= SECS_PER_HOUR;
  86. tmbuf->tm_min = rem / 60;
  87. tmbuf->tm_sec = rem % 60;
  88. /* January 1, 1970 was a Thursday. */
  89. tmbuf->tm_wday = (4 + days) % 7;
  90. if (tmbuf->tm_wday < 0)
  91. tmbuf->tm_wday += 7;
  92. y = 1970;
  93. while (days >= (rem = __isleap(y) ? 366 : 365)) {
  94. ++y;
  95. days -= rem;
  96. }
  97. while (days < 0) {
  98. --y;
  99. days += __isleap(y) ? 366 : 365;
  100. }
  101. tmbuf->tm_year = y - 1900;
  102. tmbuf->tm_yday = days;
  103. ip = __mon_lengths[__isleap(y)];
  104. for (y = 0; days >= ip[y]; ++y)
  105. days -= ip[y];
  106. tmbuf->tm_mon = y;
  107. tmbuf->tm_mday = days + 1;
  108. tmbuf->tm_isdst = -1;
  109. }
  110. #endif