kern
view src/klibc/time.c @ 80:4db99a52863e
fixed the "endianess" of the text messages in the ATA identify info block. this
is the first time I've seen wrong byteorder in ascii text, the ATA committee
should be commended.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 06 Dec 2011 13:35:39 +0200 |
parents | 92297f65aaef |
children |
line source
1 #include <stdio.h>
2 #include "time.h"
3 #include "rtc.h"
4 #include "timer.h"
5 #include "config.h"
7 #define MINSEC 60
8 #define HOURSEC (60 * MINSEC)
9 #define DAYSEC (24 * HOURSEC)
10 #define YEARDAYS(x) (is_leap_year(x) ? 366 : 365)
12 /* 1-1-1970 was a thursday */
13 #define EPOCH_WDAY 4
15 static int is_leap_year(int yr);
17 static int mdays[2][12] = {
18 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
19 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
20 };
22 static char *wday[] = {
23 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
24 };
25 static char *mon[] = {
26 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
27 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
28 };
31 time_t time(time_t *tp)
32 {
33 time_t res = start_time + nticks / TICK_FREQ_HZ;
35 if(tp) *tp = res;
36 return res;
37 }
39 char *asctime(struct tm *tm)
40 {
41 static char buf[64];
42 return asctime_r(tm, buf);
43 }
45 char *asctime_r(struct tm *tm, char *buf)
46 {
47 sprintf(buf, "%s %s %d %02d:%02d:%02d %d\n", wday[tm->tm_wday],
48 mon[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min,
49 tm->tm_sec, tm->tm_year + 1900);
50 return buf;
51 }
53 time_t mktime(struct tm *tm)
54 {
55 int i, num_years = tm->tm_year - 70;
56 int year = 1970;
57 int days = day_of_year(tm->tm_year + 1900, tm->tm_mon, tm->tm_mday - 1);
59 /* set correct yearday */
60 tm->tm_yday = days;
62 for(i=0; i<num_years; i++) {
63 days += YEARDAYS(year++);
64 }
66 /* set wday correctly */
67 tm->tm_wday = (days + EPOCH_WDAY) % 7;
69 return (time_t)days * DAYSEC + tm->tm_hour * HOURSEC +
70 tm->tm_min * MINSEC + tm->tm_sec;
71 }
73 struct tm *gmtime(time_t *tp)
74 {
75 static struct tm tm;
76 return gmtime_r(tp, &tm);
77 }
79 struct tm *gmtime_r(time_t *tp, struct tm *tm)
80 {
81 int year, days, leap, yrdays;
82 time_t t;
84 year = 1970;
85 days = *tp / DAYSEC;
86 t = *tp % DAYSEC;
88 tm->tm_wday = (days + EPOCH_WDAY) % 7;
90 while(days >= (yrdays = YEARDAYS(year))) {
91 days -= yrdays;
92 year++;
93 }
94 tm->tm_year = year - 1900;
95 tm->tm_yday = days;
97 leap = is_leap_year(year);
98 tm->tm_mon = 0;
99 while(days >= mdays[leap][tm->tm_mon]) {
100 days -= mdays[leap][tm->tm_mon++];
101 }
103 tm->tm_mday = days + 1;
105 tm->tm_hour = t / HOURSEC;
106 t %= HOURSEC;
107 tm->tm_min = t / MINSEC;
108 tm->tm_sec = t % MINSEC;
109 return tm;
110 }
112 int day_of_year(int year, int mon, int day)
113 {
114 int i, yday, leap;
116 leap = is_leap_year(year) ? 1 : 0;
117 yday = day;
119 for(i=0; i<mon; i++) {
120 yday += mdays[leap][i];
121 }
122 return yday;
123 }
125 static int is_leap_year(int yr)
126 {
127 /* exceptions first */
128 if(yr % 400 == 0) {
129 return 1;
130 }
131 if(yr % 100 == 0) {
132 return 0;
133 }
134 /* standard case */
135 return yr % 4 == 0;
136 }