time.c

Go to the documentation of this file.
00001 /* time.c */
00002 
00003 #include "routix/time.h"
00004 #include "routix/8254.h"
00005 #include <routix/kstdio.h>
00006 
00007 #ifndef __SYSTEM
00008 #include "routix/system.h"
00009 #endif
00010 
00011 
00012 static char dias_por_mes[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
00013 enum { ENERO, FEBRERO, MARZO, ABRIL, MAYO, JUNIO, JULIO, AGOSTO, SEPTIEMBRE, OCTUBRE, NOVIEMBRE, DICIEMBRE };
00014 static time_t reloj=0;
00015 
00016 
00017 byte get_value(word registro)
00018 {
00019  outportb_p(CMOS_C, registro);
00020  return(inportb_p(CMOS_V));
00021 }
00022 
00023 void set_value(word registro, byte valor)
00024 {
00025  outportb_p(CMOS_C, registro);
00026  outportb_p(CMOS_V, valor);
00027 }
00028 
00029 
00030 void init_time()
00031 {
00032 
00033  struct tm tm;
00034 
00035  int year = get_year();
00036  year = ( year >= 1970 ) ? 1900+year : 2000+year;
00037  year -= 1900;
00038 
00039  tm.tm_sec = get_sec();
00040  tm.tm_min = get_min();
00041  tm.tm_hour = get_hour();
00042  tm.tm_mday = get_dayofmonth();
00043  tm.tm_mon  = get_month() - 1;
00044  tm.tm_year = year ;
00045  tm.tm_wday = get_dayofweek();
00046  tm.tm_yday = day_of_year(tm.tm_year, tm.tm_mon, tm.tm_mday);
00047  tm.tm_isdst = 0;                                                       // Cero por ahora
00048 
00049 
00050  // Seteamos el valor del reloj
00051  reloj = mktime( &tm );
00052  kprintf("Seteando reloj: %d\n",reloj);
00053 }
00054 
00055 
00056 
00057 inline void actualizar_reloj()
00058 {
00059         reloj++;
00060 }
00061 
00062 
00063 struct tm *localtime(const time_t *clock)
00064 {
00065  static struct tm tm;
00066  time_t tod;
00067 
00068  // Valores del momento actual
00069  if ( ! clock ) {
00070   kprintf("localtime: null tod, seteando tod=reloj (%d ticks)\n",reloj);
00071   tod = reloj;
00072  }
00073 
00074  // Hay un tod especificado
00075  else {
00076   kprintf("localtime: tod especificado, tod=*clock (%d ticks)\n",*clock);
00077   tod = *clock;
00078  }
00079 
00080  // Calculamos el año
00081  for ( tm.tm_year=ANIO_INICIO; (tod -= SEC_PER_YEAR(1900+tm.tm_year)) > 0; tm.tm_year++ ) ;
00082  // Corregimos por el error en la última resta del for
00083  tod += SEC_PER_YEAR(1900+tm.tm_year);
00084 
00085  // Calculamos el mes
00086  for ( tm.tm_mon=MES_INICIO; (tod -= SEC_PER_MONTH(tm.tm_year,tm.tm_mon)) > 0; tm.tm_mon++ ) ;
00087  // Corregimos por el error en la última resta del for
00088  tod += SEC_PER_MONTH(tm.tm_year,tm.tm_mon);
00089  
00090 
00091  tm.tm_mday = (time_t) (tod / SEC_PER_DAY);
00092  tod -= (tm.tm_mday * SEC_PER_DAY);
00093  tm.tm_mday++;
00094 
00095  tm.tm_hour = (time_t) (tod / SEC_PER_HOUR);
00096  tod -= (tm.tm_hour * SEC_PER_HOUR);
00097 
00098  tm.tm_min = (time_t) (tod / SEC_PER_MIN);
00099  tm.tm_sec = tod - (tm.tm_min * SEC_PER_MIN);
00100 
00101  return &tm;
00102 }
00103 
00104 
00105 
00106 int day_of_year(int anio, int mes, int dia)
00107 {
00108  int tmp;
00109  int dias=dia;
00110 
00111  // Recorremos los meses
00112  for ( tmp=0; tmp < mes; tmp++)
00113         dias += dias_por_mes[tmp];
00114 
00115  // Correcion por año bisiesto
00116  if ( (mes > FEBRERO) && es_bisiesto(1900+anio) ) dias++;
00117 
00118  return dias;
00119 }
00120 
00121 
00122 
00123 // Calculo del tod
00124 // el tod representa la cantidad de segundos transcurridos desde un momento hasta el
00125 // 1 de enero de 1970.
00126 // Para entender la forma de calcularlo veamos un ejemplo:
00127 // queremos calcular el tod de la fecha: 25/09/1979 07:49:15
00128 //
00129 // bien, primero que todo:
00130 //
00131 // 1979 - 1970 = 9 años transcurridos
00132 // 70-71 -- 71-72 -- 72-73 -- 73-74 -- 74-75 -- 75-76 -- 76-77 -- 77-78 -- 78-79
00133 // o sea que la cantidad de segundos hasta el inicio del 79 son:
00134 //
00135 // tod += 9 * 365 * 24 * 60 * 60
00136 //
00137 // bien, no olvidemos los años bisiestos, que desde el 70 al 78 son 1972 - 1976
00138 // con lo que ajustando el tod anterior tenemos:
00139 //
00140 // tod += 2 * 1 * 24 * 60 * 60                          dos días de ajuste
00141 //
00142 // Bien, ahora debemos calcular la cantidad de segundos desde el Enero de 1979 hasta Septiembre de 1979
00143 // tod += dias_por_mes[ENERO] * 24 * 60 * 60 + dias_por_mes[FEB] * 24 * 60 * 60 + ... + dias_por_mes[AGOS] * 24 * 60 * 60
00144 // como antes, si el año es bisiesto y SI PASAMOS POR FEBRERO debemos corregir:
00145 // tod += 1 * 24 * 60 * 60
00146 //
00147 // Ahora, la cantidad de segundos desde el 1ero de Septiembre al 25 de Septiembre
00148 // tod += 24 * 24 * 60 * 60
00149 // 
00150 //
00151 // Ahora la cantidad de segundos desde las 00:00 del 25 de Septiembre a las 07:00 del mismo
00152 // tod += 7 * 60 * 60
00153 //
00154 // Ahora la cantidad de segundos desde los 0 minutos hasta los 49 minutos
00155 // tod += 49 * 60;
00156 //
00157 // Finalmente sumamos la cantidad de segundos:
00158 // tod += 15
00159 //
00160 // y obtuvimos el tod buscado.
00161 time_t mktime(struct tm *tm)
00162 {
00163  int tmp;
00164  time_t tod=0;
00165         
00166  for ( tmp=ANIO_INICIO; tmp < tm->tm_year ; tmp++ )
00167          tod += SEC_PER_YEAR(1900+tmp);
00168 
00169  for ( tmp=MES_INICIO; tmp < tm->tm_mon ; tmp++ )
00170          tod += SEC_PER_MONTH(tm->tm_year,tmp);
00171  
00172  tod += (tm->tm_mday - 1) * SEC_PER_DAY + tm->tm_hour * SEC_PER_HOUR + tm->tm_min * SEC_PER_MIN + tm->tm_sec;
00173 
00174  return tod;
00175 }
00176 
00177 
00178 
00179 
00180 
00181 // Los años bisiestos son todos los divisibles por 4 suprimiendo los divisibles por 100
00182 // y no divisibles por 400 ( la regla de calculo es válida desde 1582 ).
00183 int es_bisiesto(int year)
00184 {
00185  if ( (!(year%4)) && (year%100) ) { return 1; }
00186  else if ( !(year%400) ) { return 1;  }
00187  else return 0;
00188 }
00189 
00190 char *dias[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00191 char *mes[]  = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00192 
00193 
00194 char *asctime(const struct tm *tm)
00195 {
00196 
00197  static char string[26];
00198 
00199  //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) );
00200  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) );
00201 
00202  string[26]='\0';
00203 
00204  return string;
00205 }
00206 
00207 
00208 

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6