tm_conv.c 2.7 KB

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