tm_conv.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* This is adapted from glibc */
  2. /* Copyright (C) 1991, 1993 Free Software Foundation, Inc */
  3. #define SECS_PER_HOUR 3600L
  4. #define SECS_PER_DAY 86400L
  5. #include <features.h>
  6. #include <time.h>
  7. #include <sys/types.h>
  8. /* This structure contains all the information about a
  9. timezone given in the POSIX standard TZ envariable. */
  10. typedef struct
  11. {
  12. const char *name;
  13. /* When to change. */
  14. enum { J0, J1, M } type; /* Interpretation of: */
  15. unsigned short int m, n, d; /* Month, week, day. */
  16. unsigned int secs; /* Time of day. */
  17. long int offset; /* Seconds east of GMT (west if < 0). */
  18. /* We cache the computed time of change for a
  19. given year so we don't have to recompute it. */
  20. time_t change; /* When to change to this zone. */
  21. int computed_for; /* Year above is computed for. */
  22. } tz_rule;
  23. /* tz_rules[0] is standard, tz_rules[1] is daylight. */
  24. static tz_rule tz_rules[2];
  25. /* Warning -- this function is a stub andd always does UTC
  26. * no matter what it is given */
  27. void tzset (void)
  28. {
  29. tz_rules[0].name = tz_rules[1].name = "UTC";
  30. tz_rules[0].type = tz_rules[1].type = J0;
  31. tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0;
  32. tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0;
  33. tz_rules[0].secs = tz_rules[1].secs = 0;
  34. tz_rules[0].offset = tz_rules[1].offset = 0L;
  35. tz_rules[0].change = tz_rules[1].change = (time_t) -1;
  36. tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
  37. }
  38. static const unsigned short int __mon_lengths[2][12] = {
  39. /* Normal years. */
  40. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  41. /* Leap years. */
  42. {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
  43. };
  44. void __tm_conv(struct tm *tmbuf, time_t *t, time_t offset)
  45. {
  46. int isdst;
  47. long days, rem;
  48. register int y;
  49. register const unsigned short int *ip;
  50. timezone = -offset;
  51. days = *t / SECS_PER_DAY;
  52. rem = *t % SECS_PER_DAY;
  53. rem += offset;
  54. while (rem < 0) {
  55. rem += SECS_PER_DAY;
  56. --days;
  57. }
  58. while (rem >= SECS_PER_DAY) {
  59. rem -= SECS_PER_DAY;
  60. ++days;
  61. }
  62. tmbuf->tm_hour = rem / SECS_PER_HOUR;
  63. rem %= SECS_PER_HOUR;
  64. tmbuf->tm_min = rem / 60;
  65. tmbuf->tm_sec = rem % 60;
  66. /* January 1, 1970 was a Thursday. */
  67. tmbuf->tm_wday = (4 + days) % 7;
  68. if (tmbuf->tm_wday < 0)
  69. tmbuf->tm_wday += 7;
  70. y = 1970;
  71. while (days >= (rem = __isleap(y) ? 366 : 365)) {
  72. ++y;
  73. days -= rem;
  74. }
  75. while (days < 0) {
  76. --y;
  77. days += __isleap(y) ? 366 : 365;
  78. }
  79. tmbuf->tm_year = y - 1900;
  80. tmbuf->tm_yday = days;
  81. ip = __mon_lengths[__isleap(y)];
  82. for (y = 0; days >= ip[y]; ++y)
  83. days -= ip[y];
  84. tmbuf->tm_mon = y;
  85. tmbuf->tm_mday = days + 1;
  86. isdst = (*t >= tz_rules[0].change && *t < tz_rules[1].change);
  87. tmbuf->tm_isdst = isdst;
  88. tmbuf->tm_zone = tzname[isdst];
  89. }