Annotation of 43BSD/lib/libc/gen/ctime.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #if defined(LIBC_SCCS) && !defined(lint)
                      8: static char sccsid[] = "@(#)ctime.c    5.5 (Berkeley) 3/9/86";
                      9: #endif LIBC_SCCS and not lint
                     10: 
                     11: /*
                     12:  * This routine converts time as follows.
                     13:  * The epoch is 0000 Jan 1 1970 GMT.
                     14:  * The argument time is in seconds since then.
                     15:  * The localtime(t) entry returns a pointer to an array
                     16:  * containing
                     17:  *  seconds (0-59)
                     18:  *  minutes (0-59)
                     19:  *  hours (0-23)
                     20:  *  day of month (1-31)
                     21:  *  month (0-11)
                     22:  *  year-1970
                     23:  *  weekday (0-6, Sun is 0)
                     24:  *  day of the year
                     25:  *  daylight savings flag
                     26:  *
                     27:  * The routine calls the system to determine the local
                     28:  * timezone and whether Daylight Saving Time is permitted locally.
                     29:  * (DST is then determined by the current local rules)
                     30:  *
                     31:  * The routine does not work
                     32:  * in Saudi Arabia which runs on Solar time.
                     33:  *
                     34:  * asctime(tvec))
                     35:  * where tvec is produced by localtime
                     36:  * returns a ptr to a character string
                     37:  * that has the ascii time in the form
                     38:  *     Thu Jan 01 00:00:00 1970\n\0
                     39:  *     0123456789012345678901234 5
                     40:  *     0         1         2
                     41:  *
                     42:  * ctime(t) just calls localtime, then asctime.
                     43:  */
                     44: 
                     45: #include <sys/time.h>
                     46: #include <sys/types.h>
                     47: #include <sys/timeb.h>
                     48: 
                     49: static char    cbuf[26];
                     50: static int     dmsize[12] =
                     51: {
                     52:        31,
                     53:        28,
                     54:        31,
                     55:        30,
                     56:        31,
                     57:        30,
                     58:        31,
                     59:        31,
                     60:        30,
                     61:        31,
                     62:        30,
                     63:        31
                     64: };
                     65: 
                     66: /*
                     67:  * The following table is used for 1974 and 1975 and
                     68:  * gives the day number of the first day after the Sunday of the
                     69:  * change.
                     70:  */
                     71: struct dstab {
                     72:        int     dayyr;
                     73:        int     daylb;
                     74:        int     dayle;
                     75: };
                     76: 
                     77: static struct dstab usdaytab[] = {
                     78:        1974,   5,      333,    /* 1974: Jan 6 - last Sun. in Nov */
                     79:        1975,   58,     303,    /* 1975: Last Sun. in Feb - last Sun in Oct */
                     80:        0,      119,    303,    /* all other years: end Apr - end Oct */
                     81: };
                     82: static struct dstab ausdaytab[] = {
                     83:        1970,   400,    0,      /* 1970: no daylight saving at all */
                     84:        1971,   303,    0,      /* 1971: daylight saving from Oct 31 */
                     85:        1972,   303,    58,     /* 1972: Jan 1 -> Feb 27 & Oct 31 -> dec 31 */
                     86:        0,      303,    65,     /* others: -> Mar 7, Oct 31 -> */
                     87: };
                     88: 
                     89: /*
                     90:  * The European tables ... based on hearsay
                     91:  * Believed correct for:
                     92:  *     WE:     Great Britain, Portugal?
                     93:  *     ME:     Belgium, Luxembourg, Netherlands, Denmark, Norway,
                     94:  *             Austria, Poland, Czechoslovakia, Sweden, Switzerland,
                     95:  *             DDR, DBR, France, Spain, Hungary, Italy, Jugoslavia
                     96:  *             Finland (EE timezone, but ME dst rules)
                     97:  * Eastern European dst is unknown, we'll make it ME until someone speaks up.
                     98:  *     EE:     Bulgaria, Greece, Rumania, Turkey, Western Russia
                     99:  *
                    100:  * Ireland is unpredictable.  (Years when Easter Sunday just happens ...)
                    101:  * Years before 1983 are suspect.
                    102:  */
                    103: static struct dstab wedaytab[] = {
                    104:        1983,   89,     296,    /* 1983: end March - end Oct */
                    105:        0,      89,     303,    /* others: end March - end Oct */
                    106: };
                    107: 
                    108: static struct dstab medaytab[] = {
                    109:        1983,   89,     296,    /* 1983: end March - end Oct */
                    110:        0,      89,     272,    /* others: end March - end Sep */
                    111: };
                    112: 
                    113: /*
                    114:  * Canada, same as the US, except no early 70's fluctuations.
                    115:  * Can this really be right ??
                    116:  */
                    117: static struct dstab candaytab[] = {
                    118:        0,      119,    303,    /* all years: end Apr - end Oct */
                    119: };
                    120: 
                    121: static struct dayrules {
                    122:        int             dst_type;       /* number obtained from system */
                    123:        int             dst_hrs;        /* hours to add when dst on */
                    124:        struct  dstab * dst_rules;      /* one of the above */
                    125:        enum {STH,NTH}  dst_hemi;       /* southern, northern hemisphere */
                    126: } dayrules [] = {
                    127:        DST_USA,        1,      usdaytab,       NTH,
                    128:        DST_AUST,       1,      ausdaytab,      STH,
                    129:        DST_WET,        1,      wedaytab,       NTH,
                    130:        DST_MET,        1,      medaytab,       NTH,
                    131:        DST_EET,        1,      medaytab,       NTH,    /* XXX */
                    132:        DST_CAN,        1,      candaytab,      NTH,
                    133:        -1,
                    134: };
                    135: 
                    136: struct tm      *gmtime();
                    137: char           *ct_numb();
                    138: struct tm      *localtime();
                    139: char   *ctime();
                    140: char   *ct_num();
                    141: char   *asctime();
                    142: 
                    143: char *
                    144: ctime(t)
                    145: time_t *t;
                    146: {
                    147:        return(asctime(localtime(t)));
                    148: }
                    149: 
                    150: struct tm *
                    151: localtime(tim)
                    152: time_t *tim;
                    153: {
                    154:        register int dayno;
                    155:        register struct tm *ct;
                    156:        register dalybeg, daylend;
                    157:        register struct dayrules *dr;
                    158:        register struct dstab *ds;
                    159:        int year;
                    160:        time_t copyt;
                    161:        struct timeval curtime;
                    162:        static struct timezone zone;
                    163:        static int init = 0;
                    164: 
                    165:        if (!init) {
                    166:                gettimeofday(&curtime, &zone);
                    167:                init++;
                    168:        }
                    169:        copyt = *tim - (time_t)zone.tz_minuteswest*60;
                    170:        ct = gmtime(&copyt);
                    171:        dayno = ct->tm_yday;
                    172:        for (dr = dayrules; dr->dst_type >= 0; dr++)
                    173:                if (dr->dst_type == zone.tz_dsttime)
                    174:                        break;
                    175:        if (dr->dst_type >= 0) {
                    176:                year = ct->tm_year + 1900;
                    177:                for (ds = dr->dst_rules; ds->dayyr; ds++)
                    178:                        if (ds->dayyr == year)
                    179:                                break;
                    180:                dalybeg = ds->daylb;    /* first Sun after dst starts */
                    181:                daylend = ds->dayle;    /* first Sun after dst ends */
                    182:                dalybeg = sunday(ct, dalybeg);
                    183:                daylend = sunday(ct, daylend);
                    184:                switch (dr->dst_hemi) {
                    185:                case NTH:
                    186:                    if (!(
                    187:                       (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) &&
                    188:                       (dayno<daylend || (dayno==daylend && ct->tm_hour<1))
                    189:                    ))
                    190:                            return(ct);
                    191:                    break;
                    192:                case STH:
                    193:                    if (!(
                    194:                       (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) ||
                    195:                       (dayno<daylend || (dayno==daylend && ct->tm_hour<2))
                    196:                    ))
                    197:                            return(ct);
                    198:                    break;
                    199:                default:
                    200:                    return(ct);
                    201:                }
                    202:                copyt += dr->dst_hrs*60*60;
                    203:                ct = gmtime(&copyt);
                    204:                ct->tm_isdst++;
                    205:        }
                    206:        return(ct);
                    207: }
                    208: 
                    209: /*
                    210:  * The argument is a 0-origin day number.
                    211:  * The value is the day number of the last
                    212:  * Sunday on or before the day.
                    213:  */
                    214: static
                    215: sunday(t, d)
                    216: register struct tm *t;
                    217: register int d;
                    218: {
                    219:        if (d >= 58)
                    220:                d += dysize(t->tm_year) - 365;
                    221:        return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
                    222: }
                    223: 
                    224: struct tm *
                    225: gmtime(tim)
                    226: time_t *tim;
                    227: {
                    228:        register int d0, d1;
                    229:        long hms, day;
                    230:        register int *tp;
                    231:        static struct tm xtime;
                    232: 
                    233:        /*
                    234:         * break initial number into days
                    235:         */
                    236:        hms = *tim % 86400;
                    237:        day = *tim / 86400;
                    238:        if (hms<0) {
                    239:                hms += 86400;
                    240:                day -= 1;
                    241:        }
                    242:        tp = (int *)&xtime;
                    243: 
                    244:        /*
                    245:         * generate hours:minutes:seconds
                    246:         */
                    247:        *tp++ = hms%60;
                    248:        d1 = hms/60;
                    249:        *tp++ = d1%60;
                    250:        d1 /= 60;
                    251:        *tp++ = d1;
                    252: 
                    253:        /*
                    254:         * day is the day number.
                    255:         * generate day of the week.
                    256:         * The addend is 4 mod 7 (1/1/1970 was Thursday)
                    257:         */
                    258: 
                    259:        xtime.tm_wday = (day+7340036)%7;
                    260: 
                    261:        /*
                    262:         * year number
                    263:         */
                    264:        if (day>=0) for(d1=70; day >= dysize(d1); d1++)
                    265:                day -= dysize(d1);
                    266:        else for (d1=70; day<0; d1--)
                    267:                day += dysize(d1-1);
                    268:        xtime.tm_year = d1;
                    269:        xtime.tm_yday = d0 = day;
                    270: 
                    271:        /*
                    272:         * generate month
                    273:         */
                    274: 
                    275:        if (dysize(d1)==366)
                    276:                dmsize[1] = 29;
                    277:        for(d1=0; d0 >= dmsize[d1]; d1++)
                    278:                d0 -= dmsize[d1];
                    279:        dmsize[1] = 28;
                    280:        *tp++ = d0+1;
                    281:        *tp++ = d1;
                    282:        xtime.tm_isdst = 0;
                    283:        return(&xtime);
                    284: }
                    285: 
                    286: char *
                    287: asctime(t)
                    288: struct tm *t;
                    289: {
                    290:        register char *cp, *ncp;
                    291:        register int *tp;
                    292: 
                    293:        cp = cbuf;
                    294:        for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;);
                    295:        ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday];
                    296:        cp = cbuf;
                    297:        *cp++ = *ncp++;
                    298:        *cp++ = *ncp++;
                    299:        *cp++ = *ncp++;
                    300:        cp++;
                    301:        tp = &t->tm_mon;
                    302:        ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3];
                    303:        *cp++ = *ncp++;
                    304:        *cp++ = *ncp++;
                    305:        *cp++ = *ncp++;
                    306:        cp = ct_numb(cp, *--tp);
                    307:        cp = ct_numb(cp, *--tp+100);
                    308:        cp = ct_numb(cp, *--tp+100);
                    309:        cp = ct_numb(cp, *--tp+100);
                    310:        if (t->tm_year>=100) {
                    311:                cp[1] = '2';
                    312:                cp[2] = '0' + (t->tm_year-100) / 100;
                    313:        }
                    314:        cp += 2;
                    315:        cp = ct_numb(cp, t->tm_year+100);
                    316:        return(cbuf);
                    317: }
                    318: 
                    319: dysize(y)
                    320: {
                    321:        if((y%4) == 0)
                    322:                return(366);
                    323:        return(365);
                    324: }
                    325: 
                    326: static char *
                    327: ct_numb(cp, n)
                    328: register char *cp;
                    329: {
                    330:        cp++;
                    331:        if (n>=10)
                    332:                *cp++ = (n/10)%10 + '0';
                    333:        else
                    334:                *cp++ = ' ';
                    335:        *cp++ = n%10 + '0';
                    336:        return(cp);
                    337: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.