kern
diff src/klibc/time.c @ 41:928b0ebfff4d
merged the timer/rtc/etc from the misc branch
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 14 Jun 2011 01:19:07 +0300 |
parents | 92297f65aaef |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/klibc/time.c Tue Jun 14 01:19:07 2011 +0300 1.3 @@ -0,0 +1,136 @@ 1.4 +#include <stdio.h> 1.5 +#include "time.h" 1.6 +#include "rtc.h" 1.7 +#include "timer.h" 1.8 +#include "config.h" 1.9 + 1.10 +#define MINSEC 60 1.11 +#define HOURSEC (60 * MINSEC) 1.12 +#define DAYSEC (24 * HOURSEC) 1.13 +#define YEARDAYS(x) (is_leap_year(x) ? 366 : 365) 1.14 + 1.15 +/* 1-1-1970 was a thursday */ 1.16 +#define EPOCH_WDAY 4 1.17 + 1.18 +static int is_leap_year(int yr); 1.19 + 1.20 +static int mdays[2][12] = { 1.21 + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 1.22 + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 1.23 +}; 1.24 + 1.25 +static char *wday[] = { 1.26 + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 1.27 +}; 1.28 +static char *mon[] = { 1.29 + "Jan", "Feb", "Mar", "Apr", "May", "Jun", 1.30 + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 1.31 +}; 1.32 + 1.33 + 1.34 +time_t time(time_t *tp) 1.35 +{ 1.36 + time_t res = start_time + nticks / TICK_FREQ_HZ; 1.37 + 1.38 + if(tp) *tp = res; 1.39 + return res; 1.40 +} 1.41 + 1.42 +char *asctime(struct tm *tm) 1.43 +{ 1.44 + static char buf[64]; 1.45 + return asctime_r(tm, buf); 1.46 +} 1.47 + 1.48 +char *asctime_r(struct tm *tm, char *buf) 1.49 +{ 1.50 + sprintf(buf, "%s %s %d %02d:%02d:%02d %d\n", wday[tm->tm_wday], 1.51 + mon[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1.52 + tm->tm_sec, tm->tm_year + 1900); 1.53 + return buf; 1.54 +} 1.55 + 1.56 +time_t mktime(struct tm *tm) 1.57 +{ 1.58 + int i, num_years = tm->tm_year - 70; 1.59 + int year = 1970; 1.60 + int days = day_of_year(tm->tm_year + 1900, tm->tm_mon, tm->tm_mday - 1); 1.61 + 1.62 + /* set correct yearday */ 1.63 + tm->tm_yday = days; 1.64 + 1.65 + for(i=0; i<num_years; i++) { 1.66 + days += YEARDAYS(year++); 1.67 + } 1.68 + 1.69 + /* set wday correctly */ 1.70 + tm->tm_wday = (days + EPOCH_WDAY) % 7; 1.71 + 1.72 + return (time_t)days * DAYSEC + tm->tm_hour * HOURSEC + 1.73 + tm->tm_min * MINSEC + tm->tm_sec; 1.74 +} 1.75 + 1.76 +struct tm *gmtime(time_t *tp) 1.77 +{ 1.78 + static struct tm tm; 1.79 + return gmtime_r(tp, &tm); 1.80 +} 1.81 + 1.82 +struct tm *gmtime_r(time_t *tp, struct tm *tm) 1.83 +{ 1.84 + int year, days, leap, yrdays; 1.85 + time_t t; 1.86 + 1.87 + year = 1970; 1.88 + days = *tp / DAYSEC; 1.89 + t = *tp % DAYSEC; 1.90 + 1.91 + tm->tm_wday = (days + EPOCH_WDAY) % 7; 1.92 + 1.93 + while(days >= (yrdays = YEARDAYS(year))) { 1.94 + days -= yrdays; 1.95 + year++; 1.96 + } 1.97 + tm->tm_year = year - 1900; 1.98 + tm->tm_yday = days; 1.99 + 1.100 + leap = is_leap_year(year); 1.101 + tm->tm_mon = 0; 1.102 + while(days >= mdays[leap][tm->tm_mon]) { 1.103 + days -= mdays[leap][tm->tm_mon++]; 1.104 + } 1.105 + 1.106 + tm->tm_mday = days + 1; 1.107 + 1.108 + tm->tm_hour = t / HOURSEC; 1.109 + t %= HOURSEC; 1.110 + tm->tm_min = t / MINSEC; 1.111 + tm->tm_sec = t % MINSEC; 1.112 + return tm; 1.113 +} 1.114 + 1.115 +int day_of_year(int year, int mon, int day) 1.116 +{ 1.117 + int i, yday, leap; 1.118 + 1.119 + leap = is_leap_year(year) ? 1 : 0; 1.120 + yday = day; 1.121 + 1.122 + for(i=0; i<mon; i++) { 1.123 + yday += mdays[leap][i]; 1.124 + } 1.125 + return yday; 1.126 +} 1.127 + 1.128 +static int is_leap_year(int yr) 1.129 +{ 1.130 + /* exceptions first */ 1.131 + if(yr % 400 == 0) { 1.132 + return 1; 1.133 + } 1.134 + if(yr % 100 == 0) { 1.135 + return 0; 1.136 + } 1.137 + /* standard case */ 1.138 + return yr % 4 == 0; 1.139 +}