Annotation of 42BSD/lib/libc/gen/ctime.c, revision 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.