#ifdef __KLIBC__
#include <time.h>
#include <sys/time.h>

#define TM_YEAR_BASE    1900
#define DAYS_PER_WEEK   7
#define MONS_PER_YEAR   12
#define SECS_PER_MIN    60
#define SECS_PER_HOUR   3600
#define SECS_PER_DAY    86400
#define EPOCH_WDAY      4
#define EPOCH_YEAR      1970
#define DAYS_PER_NYEAR  365
#define DAYS_PER_LYEAR  366

#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
#define isleap(y) (LEAPS_THRU_END_OF(y)-LEAPS_THRU_END_OF(y-1))

struct tm
{
  int tm_sec;            /* Seconds.    [0-60] (1 leap second) */
  int tm_min;            /* Minutes.    [0-59] */
  int tm_hour;            /* Hours.    [0-23] */
  int tm_mday;            /* Day.        [1-31] */
  int tm_mon;            /* Month.    [0-11] */
  int tm_year;            /* Year    - 1900.  */
  int tm_wday;            /* Day of week.    [0-6] */
  int tm_yday;            /* Days in year.[0-365]    */
  int tm_isdst;            /* DST.        [-1/0/1]*/

  long int tm_gmtoff;        /* Seconds east of UTC.  */
  __const char *tm_zone;    /* Timezone abbreviation.  */
};

char *
ctime(t)
time_t *t;
{
    struct tm   *offtime();
    char    *asctime();

    return(asctime(offtime(t,0)));
}

/*
** A la X3J11
*/

char *
asctime(timeptr)
register struct tm *    timeptr;
{
    static char wday_name[DAYS_PER_WEEK][3] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    };
    static char mon_name[MONS_PER_YEAR][3] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
    static char result[26];

    (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
        wday_name[timeptr->tm_wday],
        mon_name[timeptr->tm_mon],
        timeptr->tm_mday, timeptr->tm_hour,
        timeptr->tm_min, timeptr->tm_sec,
        TM_YEAR_BASE + timeptr->tm_year);
    return result;
}

static int  mon_lengths[2][MONS_PER_YEAR] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

static int  year_lengths[2] = {
    DAYS_PER_NYEAR, DAYS_PER_LYEAR
};

struct tm *
offtime(clock, offset)
time_t *    clock;
long        offset;
{
    register struct tm *    tmp;
    register long       days;
    register long       rem;
    register int        y;
    register int        yleap;
    register int *      ip;
    static struct tm    tm;

    tmp = &tm;
    days = *clock / SECS_PER_DAY;
    rem = *clock % SECS_PER_DAY;
    rem += offset;
    while (rem < 0) {
        rem += SECS_PER_DAY;
        --days;
    }
    while (rem >= SECS_PER_DAY) {
        rem -= SECS_PER_DAY;
        ++days;
    }
    tmp->tm_hour = (int) (rem / SECS_PER_HOUR);
    rem = rem % SECS_PER_HOUR;
    tmp->tm_min = (int) (rem / SECS_PER_MIN);
    tmp->tm_sec = (int) (rem % SECS_PER_MIN);
    tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYS_PER_WEEK);
    if (tmp->tm_wday < 0)
        tmp->tm_wday += DAYS_PER_WEEK;
    y = EPOCH_YEAR;
    if (days >= 0)
        for ( ; ; ) {
            yleap = isleap(y);
            if (days < (long) year_lengths[yleap])
                break;
            ++y;
            days = days - (long) year_lengths[yleap];
        }
    else do {
        --y;
        yleap = isleap(y);
        days = days + (long) year_lengths[yleap];
    } while (days < 0);
    tmp->tm_year = y - TM_YEAR_BASE;
    tmp->tm_yday = (int) days;
    ip = mon_lengths[yleap];
    for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
        days = days - (long) ip[tmp->tm_mon];
    tmp->tm_mday = (int) (days + 1);
    tmp->tm_isdst = 0;
    tmp->tm_zone = "";
    tmp->tm_gmtoff = offset;
    return tmp;
}
#endif

