kern

annotate src/klibc/time.c @ 40:710739e33da8

- now read_rtc doesn't try to read weekday as it's probably wrong anyway, and doesn't set yearday either - mktime now fixes yearday and weekday - moved init_timer and init_rtc just before enabling the interrupts in main
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 12 Jun 2011 15:45:21 +0300
parents 92297f65aaef
children
rev   line source
nuclear@36 1 #include <stdio.h>
nuclear@36 2 #include "time.h"
nuclear@37 3 #include "rtc.h"
nuclear@37 4 #include "timer.h"
nuclear@37 5 #include "config.h"
nuclear@36 6
nuclear@36 7 #define MINSEC 60
nuclear@36 8 #define HOURSEC (60 * MINSEC)
nuclear@36 9 #define DAYSEC (24 * HOURSEC)
nuclear@37 10 #define YEARDAYS(x) (is_leap_year(x) ? 366 : 365)
nuclear@36 11
nuclear@40 12 /* 1-1-1970 was a thursday */
nuclear@40 13 #define EPOCH_WDAY 4
nuclear@40 14
nuclear@36 15 static int is_leap_year(int yr);
nuclear@36 16
nuclear@37 17 static int mdays[2][12] = {
nuclear@37 18 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
nuclear@37 19 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
nuclear@37 20 };
nuclear@36 21
nuclear@36 22 static char *wday[] = {
nuclear@36 23 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
nuclear@36 24 };
nuclear@36 25 static char *mon[] = {
nuclear@36 26 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
nuclear@36 27 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
nuclear@36 28 };
nuclear@36 29
nuclear@36 30
nuclear@37 31 time_t time(time_t *tp)
nuclear@37 32 {
nuclear@37 33 time_t res = start_time + nticks / TICK_FREQ_HZ;
nuclear@37 34
nuclear@37 35 if(tp) *tp = res;
nuclear@37 36 return res;
nuclear@37 37 }
nuclear@37 38
nuclear@36 39 char *asctime(struct tm *tm)
nuclear@36 40 {
nuclear@36 41 static char buf[64];
nuclear@37 42 return asctime_r(tm, buf);
nuclear@37 43 }
nuclear@36 44
nuclear@37 45 char *asctime_r(struct tm *tm, char *buf)
nuclear@37 46 {
nuclear@36 47 sprintf(buf, "%s %s %d %02d:%02d:%02d %d\n", wday[tm->tm_wday],
nuclear@36 48 mon[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min,
nuclear@36 49 tm->tm_sec, tm->tm_year + 1900);
nuclear@36 50 return buf;
nuclear@36 51 }
nuclear@36 52
nuclear@36 53 time_t mktime(struct tm *tm)
nuclear@36 54 {
nuclear@36 55 int i, num_years = tm->tm_year - 70;
nuclear@36 56 int year = 1970;
nuclear@36 57 int days = day_of_year(tm->tm_year + 1900, tm->tm_mon, tm->tm_mday - 1);
nuclear@36 58
nuclear@40 59 /* set correct yearday */
nuclear@40 60 tm->tm_yday = days;
nuclear@40 61
nuclear@36 62 for(i=0; i<num_years; i++) {
nuclear@37 63 days += YEARDAYS(year++);
nuclear@36 64 }
nuclear@36 65
nuclear@40 66 /* set wday correctly */
nuclear@40 67 tm->tm_wday = (days + EPOCH_WDAY) % 7;
nuclear@40 68
nuclear@36 69 return (time_t)days * DAYSEC + tm->tm_hour * HOURSEC +
nuclear@36 70 tm->tm_min * MINSEC + tm->tm_sec;
nuclear@36 71 }
nuclear@36 72
nuclear@37 73 struct tm *gmtime(time_t *tp)
nuclear@37 74 {
nuclear@37 75 static struct tm tm;
nuclear@37 76 return gmtime_r(tp, &tm);
nuclear@37 77 }
nuclear@37 78
nuclear@37 79 struct tm *gmtime_r(time_t *tp, struct tm *tm)
nuclear@37 80 {
nuclear@38 81 int year, days, leap, yrdays;
nuclear@38 82 time_t t;
nuclear@37 83
nuclear@38 84 year = 1970;
nuclear@38 85 days = *tp / DAYSEC;
nuclear@38 86 t = *tp % DAYSEC;
nuclear@38 87
nuclear@40 88 tm->tm_wday = (days + EPOCH_WDAY) % 7;
nuclear@38 89
nuclear@38 90 while(days >= (yrdays = YEARDAYS(year))) {
nuclear@38 91 days -= yrdays;
nuclear@37 92 year++;
nuclear@37 93 }
nuclear@37 94 tm->tm_year = year - 1900;
nuclear@39 95 tm->tm_yday = days;
nuclear@37 96
nuclear@37 97 leap = is_leap_year(year);
nuclear@37 98 tm->tm_mon = 0;
nuclear@38 99 while(days >= mdays[leap][tm->tm_mon]) {
nuclear@38 100 days -= mdays[leap][tm->tm_mon++];
nuclear@37 101 }
nuclear@37 102
nuclear@38 103 tm->tm_mday = days + 1;
nuclear@37 104
nuclear@37 105 tm->tm_hour = t / HOURSEC;
nuclear@37 106 t %= HOURSEC;
nuclear@37 107 tm->tm_min = t / MINSEC;
nuclear@37 108 tm->tm_sec = t % MINSEC;
nuclear@37 109 return tm;
nuclear@37 110 }
nuclear@37 111
nuclear@36 112 int day_of_year(int year, int mon, int day)
nuclear@36 113 {
nuclear@37 114 int i, yday, leap;
nuclear@36 115
nuclear@37 116 leap = is_leap_year(year) ? 1 : 0;
nuclear@37 117 yday = day;
nuclear@36 118
nuclear@36 119 for(i=0; i<mon; i++) {
nuclear@37 120 yday += mdays[leap][i];
nuclear@36 121 }
nuclear@36 122 return yday;
nuclear@36 123 }
nuclear@36 124
nuclear@36 125 static int is_leap_year(int yr)
nuclear@36 126 {
nuclear@36 127 /* exceptions first */
nuclear@36 128 if(yr % 400 == 0) {
nuclear@36 129 return 1;
nuclear@36 130 }
nuclear@36 131 if(yr % 100 == 0) {
nuclear@36 132 return 0;
nuclear@36 133 }
nuclear@36 134 /* standard case */
nuclear@36 135 return yr % 4 == 0;
nuclear@36 136 }