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

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

unix.superglobalmegacorp.com

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