time.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <time.h>
  2. #include <errno.h>
  3. #include <assert.h>
  4. #include <Kernel/Syscall.h>
  5. extern "C" {
  6. time_t time(time_t* tloc)
  7. {
  8. struct timeval tv;
  9. struct timezone tz;
  10. if (gettimeofday(&tv, &tz) < 0)
  11. return (time_t)-1;
  12. if (tloc)
  13. *tloc = tv.tv_sec;
  14. return tv.tv_sec;
  15. }
  16. int gettimeofday(struct timeval* tv, struct timezone*)
  17. {
  18. int rc = syscall(SC_gettimeofday, tv);
  19. __RETURN_WITH_ERRNO(rc, rc, -1);
  20. }
  21. char* ctime(const time_t*)
  22. {
  23. return const_cast<char*>("ctime() not implemented");
  24. }
  25. static inline bool __is_leap_year(int year)
  26. {
  27. return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400) == 0));
  28. }
  29. static const int __days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  30. static const int __seconds_per_day = 60 * 60 * 24;
  31. static void time_to_tm(struct tm* tm, time_t t)
  32. {
  33. int days = t / __seconds_per_day;
  34. int remaining = t % __seconds_per_day;
  35. tm->tm_sec = remaining % 60;
  36. remaining /= 60;
  37. tm->tm_min = remaining % 60;
  38. tm->tm_hour = remaining / 60;
  39. tm->tm_wday = (4 + days) % 7;
  40. int year;
  41. for (year = 1970; days >= 365 + __is_leap_year(year); ++year)
  42. days -= 365 + __is_leap_year(year);
  43. tm->tm_year = year - 1900;
  44. tm->tm_yday = days;
  45. tm->tm_mday = 1;
  46. if (__is_leap_year(year) && days == 59)
  47. ++tm->tm_mday;
  48. if (__is_leap_year(year) && days >= 59)
  49. --days;
  50. int month;
  51. for (month = 0; month < 11 && days >= __days_per_month[month]; ++month)
  52. days -= __days_per_month[month];
  53. tm->tm_mon = month;
  54. tm->tm_mday += days;
  55. }
  56. time_t mktime(struct tm* tm)
  57. {
  58. int days = 0;
  59. int seconds = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
  60. for (int year = 70; year < tm->tm_year; ++year)
  61. days += 365 + __is_leap_year(1900 + year);
  62. tm->tm_yday = tm->tm_mday - 1;
  63. for (int month = 0; month < tm->tm_mon; ++month)
  64. tm->tm_yday += __days_per_month[month];
  65. days += tm->tm_yday;
  66. return days * __seconds_per_day + seconds;
  67. }
  68. struct tm* localtime(const time_t* t)
  69. {
  70. if (!t)
  71. return nullptr;
  72. static struct tm tm_buf;
  73. time_to_tm(&tm_buf, *t);
  74. return &tm_buf;
  75. }
  76. struct tm* gmtime(const time_t* t)
  77. {
  78. // FIXME: This is obviously not correct. What about timezones bro?
  79. return localtime(t);
  80. }
  81. char *asctime(const struct tm*)
  82. {
  83. assert(false);
  84. }
  85. size_t strftime(char*, size_t, const char*, const struct tm*)
  86. {
  87. assert(false);
  88. }
  89. long timezone;
  90. long altzone;
  91. char* tzname[2];
  92. int daylight;
  93. void tzset()
  94. {
  95. assert(false);
  96. }
  97. }