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