initial commit
[pfinal.git] / Routix / src / time.c
blob04f08ce529b928aab8e2cb5bae59c5eb73a86b07
1 /* time.c */
3 #include "routix/time.h"
4 #include "routix/8254.h"
5 #include <routix/kstdio.h>
7 #ifndef __SYSTEM
8 #include "routix/system.h"
9 #endif
12 static char dias_por_mes[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
13 enum { ENERO, FEBRERO, MARZO, ABRIL, MAYO, JUNIO, JULIO, AGOSTO, SEPTIEMBRE, OCTUBRE, NOVIEMBRE, DICIEMBRE };
14 static time_t reloj=0;
17 byte get_value(word registro)
19 outportb_p(CMOS_C, registro);
20 return(inportb_p(CMOS_V));
23 void set_value(word registro, byte valor)
25 outportb_p(CMOS_C, registro);
26 outportb_p(CMOS_V, valor);
30 void init_time()
33 struct tm tm;
35 int year = get_year();
36 year = ( year >= 1970 ) ? 1900+year : 2000+year;
37 year -= 1900;
39 tm.tm_sec = get_sec();
40 tm.tm_min = get_min();
41 tm.tm_hour = get_hour();
42 tm.tm_mday = get_dayofmonth();
43 tm.tm_mon = get_month() - 1;
44 tm.tm_year = year ;
45 tm.tm_wday = get_dayofweek();
46 tm.tm_yday = day_of_year(tm.tm_year, tm.tm_mon, tm.tm_mday);
47 tm.tm_isdst = 0; // Cero por ahora
50 // Seteamos el valor del reloj
51 reloj = mktime( &tm );
52 kprintf("Seteando reloj: %d\n",reloj);
57 inline void actualizar_reloj()
59 reloj++;
63 struct tm *localtime(const time_t *clock)
65 static struct tm tm;
66 time_t tod;
68 // Valores del momento actual
69 if ( ! clock ) {
70 kprintf("localtime: null tod, seteando tod=reloj (%d ticks)\n",reloj);
71 tod = reloj;
74 // Hay un tod especificado
75 else {
76 kprintf("localtime: tod especificado, tod=*clock (%d ticks)\n",*clock);
77 tod = *clock;
80 // Calculamos el año
81 for ( tm.tm_year=ANIO_INICIO; (tod -= SEC_PER_YEAR(1900+tm.tm_year)) > 0; tm.tm_year++ ) ;
82 // Corregimos por el error en la última resta del for
83 tod += SEC_PER_YEAR(1900+tm.tm_year);
85 // Calculamos el mes
86 for ( tm.tm_mon=MES_INICIO; (tod -= SEC_PER_MONTH(tm.tm_year,tm.tm_mon)) > 0; tm.tm_mon++ ) ;
87 // Corregimos por el error en la última resta del for
88 tod += SEC_PER_MONTH(tm.tm_year,tm.tm_mon);
91 tm.tm_mday = (time_t) (tod / SEC_PER_DAY);
92 tod -= (tm.tm_mday * SEC_PER_DAY);
93 tm.tm_mday++;
95 tm.tm_hour = (time_t) (tod / SEC_PER_HOUR);
96 tod -= (tm.tm_hour * SEC_PER_HOUR);
98 tm.tm_min = (time_t) (tod / SEC_PER_MIN);
99 tm.tm_sec = tod - (tm.tm_min * SEC_PER_MIN);
101 return &tm;
106 int day_of_year(int anio, int mes, int dia)
108 int tmp;
109 int dias=dia;
111 // Recorremos los meses
112 for ( tmp=0; tmp < mes; tmp++)
113 dias += dias_por_mes[tmp];
115 // Correcion por año bisiesto
116 if ( (mes > FEBRERO) && es_bisiesto(1900+anio) ) dias++;
118 return dias;
123 // Calculo del tod
124 // el tod representa la cantidad de segundos transcurridos desde un momento hasta el
125 // 1 de enero de 1970.
126 // Para entender la forma de calcularlo veamos un ejemplo:
127 // queremos calcular el tod de la fecha: 25/09/1979 07:49:15
129 // bien, primero que todo:
131 // 1979 - 1970 = 9 años transcurridos
132 // 70-71 -- 71-72 -- 72-73 -- 73-74 -- 74-75 -- 75-76 -- 76-77 -- 77-78 -- 78-79
133 // o sea que la cantidad de segundos hasta el inicio del 79 son:
135 // tod += 9 * 365 * 24 * 60 * 60
137 // bien, no olvidemos los años bisiestos, que desde el 70 al 78 son 1972 - 1976
138 // con lo que ajustando el tod anterior tenemos:
140 // tod += 2 * 1 * 24 * 60 * 60 dos días de ajuste
142 // Bien, ahora debemos calcular la cantidad de segundos desde el Enero de 1979 hasta Septiembre de 1979
143 // tod += dias_por_mes[ENERO] * 24 * 60 * 60 + dias_por_mes[FEB] * 24 * 60 * 60 + ... + dias_por_mes[AGOS] * 24 * 60 * 60
144 // como antes, si el año es bisiesto y SI PASAMOS POR FEBRERO debemos corregir:
145 // tod += 1 * 24 * 60 * 60
147 // Ahora, la cantidad de segundos desde el 1ero de Septiembre al 25 de Septiembre
148 // tod += 24 * 24 * 60 * 60
151 // Ahora la cantidad de segundos desde las 00:00 del 25 de Septiembre a las 07:00 del mismo
152 // tod += 7 * 60 * 60
154 // Ahora la cantidad de segundos desde los 0 minutos hasta los 49 minutos
155 // tod += 49 * 60;
157 // Finalmente sumamos la cantidad de segundos:
158 // tod += 15
160 // y obtuvimos el tod buscado.
161 time_t mktime(struct tm *tm)
163 int tmp;
164 time_t tod=0;
166 for ( tmp=ANIO_INICIO; tmp < tm->tm_year ; tmp++ )
167 tod += SEC_PER_YEAR(1900+tmp);
169 for ( tmp=MES_INICIO; tmp < tm->tm_mon ; tmp++ )
170 tod += SEC_PER_MONTH(tm->tm_year,tmp);
172 tod += (tm->tm_mday - 1) * SEC_PER_DAY + tm->tm_hour * SEC_PER_HOUR + tm->tm_min * SEC_PER_MIN + tm->tm_sec;
174 return tod;
181 // Los años bisiestos son todos los divisibles por 4 suprimiendo los divisibles por 100
182 // y no divisibles por 400 ( la regla de calculo es válida desde 1582 ).
183 int es_bisiesto(int year)
185 if ( (!(year%4)) && (year%100) ) { return 1; }
186 else if ( !(year%400) ) { return 1; }
187 else return 0;
190 char *dias[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
191 char *mes[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
194 char *asctime(const struct tm *tm)
197 static char string[26];
199 //kprintf("%s %s %d %d:%d:%d %d\n", dias[tm->tm_wday], mes[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (1900 + tm->tm_year) );
200 kprintf("%s %s %d %d:%d:%d %d\n", dias[0], mes[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (1900 + tm->tm_year) );
202 string[26]='\0';
204 return string;