⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timezone.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Copyright (c) 1990-2001 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2000-Apr-09 or later  (the contents of which are also included in zip.h) for terms of use.  If, for some reason, all these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//* Replacement time library functions, based on platform independent public * domain timezone code from ftp://elsie.nci.nih.gov/pub, with mktime and * mkgmtime from our own mktime.c in Zip. * * Contains:  tzset() *            __tzset() *            gmtime() *            localtime() *            mktime() *            mkgmtime() *            GetPlatformLocalTimezone()  [different versions] *//* HISTORY/CHANGES * 17 Jun 00, Paul Kienitz, added the PD-based tzset(), localtime(), and so on *            to amiga/filedate.c, replacing GNU-based functions which had *            replaced time_lib.c, both having been rejected for licensing *            reasons.  Support for timezone files and leap seconds was removed. * * 23 Aug 00, Paul Kienitz, split into separate timezone.c file, made platform *            independent, copied in mktime() and mkgmtime() from Zip, renamed *            locale_TZ as GetPlatformLocalTimezone(), for use as a generic *            hook by other platforms. */#ifndef __timezone_c#define __timezone_c#include "zip.h"#include "timezone.h"#include <ctype.h>#include <errno.h>#ifdef IZTZ_DEFINESTDGLOBALSlong timezone = 0;int daylight = 0;char *tzname[2];#endif#ifndef IZTZ_GETLOCALETZINFO#  define IZTZ_GETLOCALETZINFO(ptzstruct, pgenrulefunct) (FALSE)#endifint real_timezone_is_set = FALSE;       /* set by tzset() */#define TZDEFRULESTRING ",M4.1.0,M10.5.0"#define TZDEFAULT       "EST5EDT"#define SECSPERMIN      60#define MINSPERHOUR     60#define HOURSPERDAY     24#define DAYSPERWEEK     7#define DAYSPERNYEAR    365#define DAYSPERLYEAR    366#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)#define SECSPERDAY      ((long) SECSPERHOUR * HOURSPERDAY)#define MONSPERYEAR 12#define EPOCH_WDAY      4     /* Jan 1, 1970 was thursday */#define EPOCH_YEAR      1970#define TM_YEAR_BASE    1900#define FIRST_GOOD_YEAR ((time_t) -1 < (time_t) 1 ? EPOCH_YEAR-68 : EPOCH_YEAR)#define LAST_GOOD_YEAR  (EPOCH_YEAR + ((time_t) -1 < (time_t) 1 ? 67 : 135))#define YDAYS(month, year) yr_days[leap(year)][month]/* Nonzero if `y' is a leap year, else zero. */#define leap(y)  (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)/* Number of leap years from EPOCH_YEAR  to `y' (not including `y' itself). */#define _P4      ((EPOCH_YEAR / 4) * 4 + 1)#define _P100    ((EPOCH_YEAR / 100) * 100 + 1)#define _P400    ((EPOCH_YEAR / 400) * 400 + 1)#define nleap(y) (((y) - _P4) / 4 - ((y) - _P100) / 100 + ((y) - _P400) / 400)/* Length of month `m' (0 .. 11) */#define monthlen(m, y) (yr_days[0][(m)+1] - yr_days[0][m] + \                        ((m) == 1 && leap(y)))/* internal module-level constants */#ifndef IZ_MKTIME_ONLYstatic ZCONST char  gmt[] = "GMT";static ZCONST int    mon_lengths[2][MONSPERYEAR] = {    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }};#endif /* !IZ_MKTIME_ONLY */static ZCONST int    yr_days[2][MONSPERYEAR+1] = {    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }};#ifndef IZ_MKTIME_ONLYstatic ZCONST int   year_lengths[2] = {    DAYSPERNYEAR, DAYSPERLYEAR};/* internal variables */static struct state statism;/* prototypes of static functions */static time_t transtime OF((ZCONST time_t janfirst, ZCONST int year,                            ZCONST struct rule * ZCONST rulep,                            ZCONST long offset));static void generate_transitions OF((register struct state * ZCONST sp,                                     ZCONST struct rule * ZCONST start,                                     ZCONST struct rule * ZCONST end));static ZCONST char *getzname OF((ZCONST char *strp));static ZCONST char *getnum OF((ZCONST char *strp, int * ZCONST nump,                               ZCONST int min, ZCONST int max));static ZCONST char *getsecs OF((ZCONST char *strp, long * ZCONST secsp));static ZCONST char *getoffset OF((ZCONST char *strp, long * ZCONST offsetp));static ZCONST char *getrule OF((ZCONST char *strp, struct rule * ZCONST rulep));static int Parse_TZ OF((ZCONST char *name, register struct state * ZCONST sp));static time_t transtime(janfirst, year, rulep, offset)     ZCONST time_t janfirst;     ZCONST int year;     ZCONST struct rule * ZCONST rulep;     ZCONST long offset;{    register int    leapyear;    register time_t value;    register int    i;    int             d, m1, yy0, yy1, yy2, dow;    value = 0;    leapyear = leap(year);    switch (rulep->r_type) {    case JULIAN_DAY:        /*        ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap        ** years.        ** In non-leap years, or if the day number is 59 or less, just        ** add SECSPERDAY times the day number-1 to the time of        ** January 1, midnight, to get the day.        */        value = janfirst + (rulep->r_day - 1) * SECSPERDAY;        if (leapyear && rulep->r_day >= 60)            value += SECSPERDAY;        break;    case DAY_OF_YEAR:        /*        ** n - day of year.        ** Just add SECSPERDAY times the day number to the time of        ** January 1, midnight, to get the day.        */        value = janfirst + rulep->r_day * SECSPERDAY;        break;    case MONTH_NTH_DAY_OF_WEEK:        /*        ** Mm.n.d - nth "dth day" of month m.        */        value = janfirst;/*        for (i = 0; i < rulep->r_mon - 1; ++i)            value += mon_lengths[leapyear][i] * SECSPERDAY;*/        value += yr_days[leapyear][rulep->r_mon - 1] * SECSPERDAY;        /*        ** Use Zeller's Congruence to get day-of-week of first day of        ** month.        */        m1 = (rulep->r_mon + 9) % 12 + 1;        yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;        yy1 = yy0 / 100;        yy2 = yy0 % 100;        dow = ((26 * m1 - 2) / 10 +            1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;        if (dow < 0)            dow += DAYSPERWEEK;        /*        ** "dow" is the day-of-week of the first day of the month.  Get        ** the day-of-month (zero-origin) of the first "dow" day of the        ** month.        */        d = rulep->r_day - dow;        if (d < 0)            d += DAYSPERWEEK;        for (i = 1; i < rulep->r_week; ++i) {            if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])                break;            d += DAYSPERWEEK;        }        /*        ** "d" is the day-of-month (zero-origin) of the day we want.        */        value += d * SECSPERDAY;        break;    }    /*    ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in    ** question.  To get the Epoch-relative time of the specified local    ** time on that day, add the transition time and the current offset    ** from UTC.    */    return value + rulep->r_time + offset;}static void generate_transitions(sp, start, end)     register struct state * ZCONST sp;     ZCONST struct rule * ZCONST start;     ZCONST struct rule * ZCONST end;{    register int             year;    register time_t          janfirst;    time_t                   starttime;    time_t                   endtime;    long                     stdoffset = -sp->ttis[0].tt_gmtoff;    long                     dstoffset = -sp->ttis[1].tt_gmtoff;    register time_t *        atp;    register unsigned char * typep;    /*    ** Two transitions per year, from EPOCH_YEAR to LAST_GOOD_YEAR.    */    sp->timecnt = 2 * (LAST_GOOD_YEAR - EPOCH_YEAR + 1);    atp = sp->ats;    typep = sp->types;    janfirst = 0;    for (year = EPOCH_YEAR; year <= LAST_GOOD_YEAR; ++year) {        starttime = transtime(janfirst, year, start, stdoffset);        endtime = transtime(janfirst, year, end, dstoffset);        if (starttime > endtime) {            *atp++ = endtime;            *typep++ = 0;   /* DST ends */            *atp++ = starttime;            *typep++ = 1;   /* DST begins */        } else {            *atp++ = starttime;            *typep++ = 1;   /* DST begins */            *atp++ = endtime;            *typep++ = 0;   /* DST ends */        }        janfirst += year_lengths[leap(year)] * SECSPERDAY;    }}static ZCONST char *getzname(strp)     ZCONST char *strp;{    register char   c;    while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&        c != '+')            ++strp;    return strp;}static ZCONST char *getnum(strp, nump, min, max)     ZCONST char *strp;     int * ZCONST nump;     ZCONST int min;     ZCONST int max;{    register char   c;    register int    num;    if (strp == NULL || !isdigit(c = *strp))        return NULL;    num = 0;    do {        num = num * 10 + (c - '0');        if (num > max)            return NULL;    /* illegal value */        c = *++strp;    } while (isdigit(c));    if (num < min)        return NULL;        /* illegal value */    *nump = num;    return strp;}static ZCONST char *getsecs(strp, secsp)     ZCONST char *strp;     long * ZCONST secsp;{    int num;    /*    ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like    ** "M10.4.6/26", which does not conform to Posix,    ** but which specifies the equivalent of    ** ``02:00 on the first Sunday on or after 23 Oct''.    */    strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);    if (strp == NULL)        return NULL;    *secsp = num * (long) SECSPERHOUR;    if (*strp == ':') {        ++strp;        strp = getnum(strp, &num, 0, MINSPERHOUR - 1);        if (strp == NULL)            return NULL;        *secsp += num * SECSPERMIN;        if (*strp == ':') {            ++strp;            /* `SECSPERMIN' allows for leap seconds.  */            strp = getnum(strp, &num, 0, SECSPERMIN);            if (strp == NULL)                return NULL;            *secsp += num;        }    }    return strp;}static ZCONST char *getoffset(strp, offsetp)     ZCONST char *strp;     long * ZCONST offsetp;{    register int    neg = 0;    if (*strp == '-') {        neg = 1;        ++strp;    } else if (*strp == '+')        ++strp;    strp = getsecs(strp, offsetp);    if (strp == NULL)        return NULL;        /* illegal time */    if (neg)        *offsetp = -*offsetp;    return strp;}static ZCONST char *getrule(strp, rulep)     ZCONST char *strp;     struct rule * ZCONST rulep;{    if (*strp == 'J') {        /*        ** Julian day.        */        rulep->r_type = JULIAN_DAY;        ++strp;        strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);    } else if (*strp == 'M') {        /*        ** Month, week, day.        */        rulep->r_type = MONTH_NTH_DAY_OF_WEEK;        ++strp;        strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);        if (strp == NULL)            return NULL;        if (*strp++ != '.')            return NULL;        strp = getnum(strp, &rulep->r_week, 1, 5);        if (strp == NULL)            return NULL;        if (*strp++ != '.')            return NULL;        strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);    } else if (isdigit(*strp)) {        /*        ** Day of year.        */        rulep->r_type = DAY_OF_YEAR;        strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);    } else  return NULL;        /* invalid format */    if (strp == NULL)        return NULL;    if (*strp == '/') {        /*        ** Time specified.        */        ++strp;        strp = getsecs(strp, &rulep->r_time);    } else        rulep->r_time = 2 * SECSPERHOUR;    /* default = 2:00:00 */    return strp;}static int Parse_TZ(name, sp)     ZCONST char *name;     register struct state * ZCONST sp;{    ZCONST char *            stdname;    ZCONST char *            dstname;    size_t                   stdlen;    size_t                   dstlen;    long                     stdoffset;    long                     dstoffset;    register char *          cp;    dstname = NULL;    stdname = name;    name = getzname(name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -