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 +}