stdlibc: +gettimeofday()
[meinos.git] / apps / lib / stdlibc / sys_time.c
blobc8fa365eaf9a8cbe408fc1c75e6df65ecc728054
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/time.h>
20 #include <time.h>
21 #include <cmos.h>
23 static time_t start_time = 0;
24 static clock_t start_ticks;
26 /**
27 * Checks whether year is a leap year
28 * @param year Year to check
29 * @return If year is a leap year
31 static int is_leapyear(unsigned int year) {
32 if (year%400==0) return 1;
33 else if (year%100==0) return 0;
34 else if (year%4==0) return 1;
35 else return 0;
38 /**
39 * Gets yday
40 * @param tm tm to get yday for
42 static void getyday(struct tm *tm) {
43 unsigned int mdays[12] = {
44 31,
45 31+28,
46 31+28+31,
47 31+28+31+30,
48 31+28+31+30+31,
49 31+28+31+30+31+30,
50 31+28+31+30+31+30+31,
51 31+28+31+30+31+30+31+31,
52 31+28+31+30+31+30+31+31+30,
53 31+28+31+30+31+30+31+31+30+31,
54 31+28+31+30+31+30+31+31+30+31+30,
55 31+28+31+30+31+30+31+31+30+31+30+31
58 tm->tm_yday = (tm->tm_mon>0?mdays[tm->tm_mon-1]:0)+tm->tm_mday;
59 if (is_leapyear(tm->tm_year+1900)) tm->tm_yday++;
62 /**
63 * Gets mday
64 * @param tm tm to get mday for
66 static void getwday(struct tm *tm) {
67 unsigned int doomsdays[] = {1,6,4,2};
68 unsigned int year = tm->tm_year+1900;
69 unsigned int dday_idx = (year/100)%4;
70 unsigned int step1 = (year%100)/12;
71 unsigned int step2 = (year%100)%12;
72 unsigned int step3 = step2/4;
73 unsigned int dday_year = (doomsdays[dday_idx]+((step1+step2+step3)%7))%7;
74 unsigned int january0 = dday_year+(7-((59+is_leapyear(year)?1:0)%7));
75 tm->tm_wday = ((january0+(tm->tm_yday%7))%7)-1;
78 /**
79 * Gets the date and time
80 * @param tp Time pointer
81 * @return Success?
83 int gettimeofday(struct timeval *tp,void *tzp) {
84 if (start_time==0) {
85 struct tm tm = {
86 .tm_sec = cmos_getsecond(),
87 .tm_min = cmos_getminute(),
88 .tm_hour = cmos_gethour(),
89 .tm_mday = cmos_getday(),
90 .tm_mon = cmos_getmonth()-1,
91 .tm_year = cmos_getyear()-1900
93 getyday(&tm);
94 getwday(&tm);
96 start_time = mktime(&tm);
97 start_ticks = clock();
100 tp->tv_sec = start_time+(clock()-start_ticks)/CLOCKS_PER_SEC;
101 tp->tv_usec = ((clock()-start_ticks)*1000000/CLOCKS_PER_SEC)%1000000;
103 return 0;