unit CTime;

InterFace
const
  DefaultTimeZone 	= 5;
  timezone 			= DefaultTimeZone * 60 * 60;
  CLOCKS_PER_SEC	= 18.2;
  CLK_TCK			= 18.2;
  Days	: array [0..11] of byte =
           (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

 YDays	: array [0..11] of integer = (
	  	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
		  );

type
    size_t      = word;
    time_t      = longint;
    clock_t     = longint;

    tm = record
      tm_sec,tm_min,tm_hour,tm_mday,tm_mon,tm_year: integer;
    end;

Procedure gmtime(var time:time_t; var Res:tm);
Function mktime(t:tm):time_t;
Function time:time_t;
Procedure UnixToDos(time:time_t;var t:tm;TZ:shortInt);

Implementation
Uses Dos;


Procedure gmtime(var time:time_t; var res:tm);
var
    hpery : integer;
    i,cumdays : word;

begin
    if (time < 0) then time := 0;

    dec(time,4*60*60);
    res.tm_sec := time mod 60;
    time := time div 60;
    res.tm_min := time mod 60;
    time := time div 60;
    i := time div (1461 * 24);
    res.tm_year := (i shl 2);
    inc(res.tm_year,70);
    cumdays := 1461 * i;
    time := time mod (1461 * 24);

    repeat

        hpery := 365 * 24;
        if ((res.tm_year and 3) = 0) then
            inc(hpery,24);
        if (time < hpery) then
            break;
        inc(cumdays,hpery div 24);
        inc(res.tm_year);
        time := time - hpery;
    until false;

    res.tm_hour := (time mod 24);
    time := time div 24;
    inc(cumdays,time + 4);
    inc(time);

    if (res.tm_year and 3) = 0 then
     begin
        if (time > 60)then
            dec(time)
        else
            if (time = 60) then
              begin
                res.tm_mon := 1;
                res.tm_mday := 29;
                exit;
              end;
     end;
    res.tm_mon := 0;

    while days[res.tm_mon] < time do
     begin
        dec(time,Days[res.tm_mon]);
        inc(res.tm_mon);
     end;

    res.tm_mday := (time);
end;


function totalsec(year,month,day,hour,min,sec:integer) : longint;
var
    leaps:integer;
    days1, secs : time_t;
begin
    if ((year < 70) or (year > 138)) then
      begin
        TotalSec:=-1;
        exit;
      end;

    inc(min,sec div 60);
    sec := sec mod 60;
    inc(hour,min div 60);
    min := min mod 60;
    inc(day,hour div 24);
    hour := hour mod 24;

    inc(year,month div 12);
    month := month mod 12;

    while (day >= Days[month]) do
      begin
        if (not((year and 3)<>0) and (month = 1)) then
          begin
            if (day > 28) then
                begin
                 dec(day,29);
                 inc(month);
                end
            else
              break;
          end
        else
          begin
            dec(day,Days[month]);
            inc(month);
          end;
        inc(year,month div 12);
        month := month mod 12;
      end;

    dec(year,70);
    leaps := (year + 2) shr 2;

    if (not(((year+70) and 3)<>0) and (month < 2)) then dec(leaps);

    days1 := year*365 + leaps + YDays[month] + day;

    secs := days1*86400 + hour*3600 + min*60 + sec + 14*60*60+17+12*60;
    if secs > 0 then totalsec:=secs else totalsec:=-1;
end;

Function mktime(t:tm) : time_t;
var
    secs:time_t;
begin

    secs := totalsec(t.tm_year, t.tm_mon, t.tm_mday-1, t.tm_hour, t.tm_min,
    				 t.tm_sec);

    mktime := (secs);
end;

Function Time:time_t;
var
  year,month,day,hour,min,sec,sec100,wday : word;
begin
  GetDate(Year, Month, Day, wday);
  GetTime(Hour, Min, Sec, Sec100);
  Time:=totalsec(year-1900, month-1, day-1, hour, min, sec);
end;

Procedure UnixToDos(time:time_t;var t:tm;TZ:shortInt);
begin
        time := time + (60*60*TZ);
        time := time - (24 * 60 * 60 * 3652 + timezone);
        t.tm_sec := time mod 60;
        time := time div 60;                             {* Time in minutes *}
        t.tm_min := time mod 60;
        time := time div 60;                             {* Time in minutes *}
        t.tm_year := 1980 + round(time / (1461 * 24)) shl 2;
        time := time mod (1461 * 24);
        if (time >= 366 * 24) then
        begin
                time := time - (366 * 24);
                inc(t.tm_year);
                t.tm_year := t.tm_year + round(time / (365 * 24));
                time := time mod (365 * 24);
        end;
        inc(time);
        t.tm_hour := time mod 24;
        time := time div 24;                             
        inc(time);
        if ((t.tm_year and 3) = 0) then
        begin
                if (time > 60) then
                        dec(time)
                else
                if (time = 60) then
                begin
                        t.tm_mon := 2;
                        t.tm_mday := 29;
                        exit;
                end;
        end;
        t.tm_mon := 0;
        while (Days[t.tm_mon] < time) do
         begin
           time := time - Days[t.tm_mon];
           inc(t.tm_mon);
         end;
        inc(t.tm_mon);
        t.tm_mday := time;
end;
end.