Beispiel #1
0
int
ggmtime(struct tm *tm, double l_clock)
{
    /* l_clock is relative to ZERO_YEAR, jan 1, 00:00:00,defined in plot.h */
    int i, days;

    /* dodgy way of doing wday - i hope it works ! */
    int wday = JAN_FIRST_WDAY;	/* eg 6 for 2000 */

    FPRINTF((stderr, "%g seconds = ", l_clock));
    if (fabs(l_clock) > 1.e12) {  /* Some time in the year 33688 */
        int_warn(NO_CARET, "time value out of range");
        return(-1);
    }

    tm->tm_year = ZERO_YEAR;
    tm->tm_mday = tm->tm_yday = tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
    if (l_clock < 0) {
        while (l_clock < 0) {
            int days_in_year = gdysize(--tm->tm_year);
            l_clock += days_in_year * DAY_SEC;	/* 24*3600 */
            /* adding 371 is noop in modulo 7 arithmetic, but keeps wday +ve */
            wday += 371 - days_in_year;
        }
    } else {
        for (;;) {
            int days_in_year = gdysize(tm->tm_year);
            if (l_clock < days_in_year * DAY_SEC)
                break;
            l_clock -= days_in_year * DAY_SEC;
            tm->tm_year++;
            /* only interested in result modulo 7, but %7 is expensive */
            wday += (days_in_year - 364);
        }
    }
    tm->tm_yday = (int) (l_clock / DAY_SEC);
    l_clock -= tm->tm_yday * DAY_SEC;
    tm->tm_hour = (int) l_clock / 3600;
    l_clock -= tm->tm_hour * 3600;
    tm->tm_min = (int) l_clock / 60;
    l_clock -= tm->tm_min * 60;
    tm->tm_sec = (int) l_clock;

    days = tm->tm_yday;

    /* wday%7 should be day of week of first day of year */
    tm->tm_wday = (wday + days) % 7;

    while (days >= (i = mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365)))) {
        days -= i;
        tm->tm_mon++;
    }
    tm->tm_mday = days + 1;

    FPRINTF((stderr, "broken-down time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));

    return (0);
}
Beispiel #2
0
/* time_t  */
double
gtimegm(struct tm *tm)
{
    int i;
    /* returns sec from year ZERO_YEAR, defined in gp_time.h */
    double dsec = 0.;

    if (tm->tm_year < ZERO_YEAR) {
        for (i = tm->tm_year; i < ZERO_YEAR; i++) {
            dsec -= (double) gdysize(i);
        }
    } else {
        for (i = ZERO_YEAR; i < tm->tm_year; i++) {
            dsec += (double) gdysize(i);
        }
    }
    if (tm->tm_mday > 0) {
        for (i = 0; i < tm->tm_mon; i++) {
            dsec += (double) mndday[i] + (i == 1 && (gdysize(tm->tm_year) > 365));
        }
        dsec += (double) tm->tm_mday - 1;
    } else {
        dsec += (double) tm->tm_yday;
    }
    dsec *= (double) 24;

    dsec += tm->tm_hour;
    dsec *= 60.0;
    dsec += tm->tm_min;
    dsec *= 60.0;
    dsec += tm->tm_sec;

    FPRINTF((stderr, "broken-down time : %02d/%02d/%d:%02d:%02d:%02d = %g seconds\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour,
             tm->tm_min, tm->tm_sec, dsec));

    return (dsec);
}
Beispiel #3
0
char *
gstrptime(char *s, char *fmt, struct tm *tm, double *usec)
{
    int yday = 0;
    TBOOLEAN sanity_check_date = FALSE;

    tm->tm_mday = 1;
    tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
    /* make relative times work (user-defined tic step) */
    tm->tm_year = ZERO_YEAR;

    /* Fractional seconds will be returned separately, since
     * there is no slot for the fraction in struct tm.
     */
    *usec = 0.0;

    /* we do not yet calculate wday or yday, so make them illegal
     * [but yday will be read by %j]
     */
    tm->tm_yday = tm->tm_wday = -1;

    /* If the format requests explicit day, month, or year, then we will
     * do sanity checking to make sure the input makes sense.
     * For backward compatibility with gnuplot versions through 4.6.6
     * hour, minute, seconds default to zero with no error return
     * if the corresponding field cannot be found or interpreted.
     */
    if (strstr(fmt,"%d")) {
        tm->tm_mday = -1;
        sanity_check_date = TRUE;
    }
    if (strstr(fmt,"%y") || strstr(fmt,"%Y")) {
        tm->tm_year = -1;
        sanity_check_date = TRUE;
    }
    if (strstr(fmt,"%m") || strstr(fmt,"%B") || strstr(fmt,"%b")) {
        tm->tm_mon = -1;
        sanity_check_date = TRUE;
    }


    while (*fmt) {
        if (*fmt != '%') {
            if (*fmt == ' ') {
                /* space in format means zero or more spaces in input */
                while (*s == ' ')
                    ++s;
                ++fmt;
                continue;
            } else if (*fmt == *s) {
                ++s;
                ++fmt;
                continue;
            } else
                break;		/* literal match has failed */
        }
        /* we are processing a percent escape */

        switch (*++fmt) {
        case 'b':		/* abbreviated month name */
        {
            int m;

            for (m = 0; m < 12; ++m)
                if (strncasecmp(s, abbrev_month_names[m],
                                strlen(abbrev_month_names[m])) == 0) {
                    s += strlen(abbrev_month_names[m]);
                    goto found_abbrev_mon;
                }
            /* get here => not found */
            int_warn(DATAFILE, "Bad abbreviated month name");
            m = 0;
found_abbrev_mon:
            tm->tm_mon = m;
            break;
        }

        case 'B':		/* full month name */
        {
            int m;

            for (m = 0; m < 12; ++m)
                if (strncasecmp(s, full_month_names[m],
                                strlen(full_month_names[m])) == 0) {
                    s += strlen(full_month_names[m]);
                    goto found_full_mon;
                }
            /* get here => not found */
            int_warn(DATAFILE, "Bad full month name");
            m = 0;
found_full_mon:
            tm->tm_mon = m;
            break;
        }

        case 'd':		/* read a day of month */
            s = read_int(s, 2, &tm->tm_mday);
            break;

        case 'm':		/* month number */
            s = read_int(s, 2, &tm->tm_mon);
            --tm->tm_mon;
            break;

        case 'y':		/* year number */
            s = read_int(s, 2, &tm->tm_year);
            /* In line with the current UNIX98 specification by
             * The Open Group and major Unix vendors,
             * two-digit years 69-99 refer to the 20th century, and
             * values in the range 00-68 refer to the 21st century.
             */
            if (tm->tm_year <= 68)
                tm->tm_year += 100;
            tm->tm_year += 1900;
            break;

        case 'Y':
            s = read_int(s, 4, &tm->tm_year);
            break;

        case 'j':
            s = read_int(s, 3, &tm->tm_yday);
            tm->tm_yday--;
            sanity_check_date = TRUE;
            yday++;
            break;

        case 'H':
            s = read_int(s, 2, &tm->tm_hour);
            break;

        case 'M':
            s = read_int(s, 2, &tm->tm_min);
            break;

        case 'S':
            s = read_int(s, 2, &tm->tm_sec);
            if (*s == '.' || (decimalsign && *s == *decimalsign))
                *usec = atof(s);
            break;


        case 's':
            /* read EPOCH data
             * EPOCH is the std. unix timeformat seconds since 01.01.1970 UTC
             */
        {
            char  *fraction = strchr(s, decimalsign ? *decimalsign : '.');
            double ufraction = 0;
            double when = strtod (s, &s) - SEC_OFFS_SYS;
            ggmtime(tm, when);
            if (fraction && fraction < s)
                ufraction = atof(fraction);
            if (ufraction < 1.)		/* Filter out e.g. 123.456e7 */
                *usec = ufraction;
            break;
        }

        default:
            int_warn(DATAFILE, "Bad time format in string");
        }
        fmt++;
    }

    FPRINTF((stderr, "read date-time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));

    /* now sanity check the date/time entered, normalising if necessary
     * read_int cannot read a -ve number, but can read %m=0 then decrement
     * it to -1
     */

#define S (tm->tm_sec)
#define M (tm->tm_min)
#define H (tm->tm_hour)

    if (S >= 60) {
        M += S / 60;
        S %= 60;
    }
    if (M >= 60) {
        H += M / 60;
        M %= 60;
    }
    if (H >= 24) {
        if (yday)
            tm->tm_yday += H / 24;
        tm->tm_mday += H / 24;
        H %= 24;
    }
#undef S
#undef M
#undef H

    FPRINTF((stderr, "normalised time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));

    if (sanity_check_date) {
        if (yday) {

            if (tm->tm_yday < 0) {
                // int_error(DATAFILE, "Illegal day of year");
                return (NULL);
            }

            /* we just set month to jan, day to yday, and let the
             * normalising code do the work.
             */

            tm->tm_mon = 0;
            /* yday is 0->365, day is 1->31 */
            tm->tm_mday = tm->tm_yday + 1;
        }
        if (tm->tm_mon < 0) {
            // int_error(DATAFILE, "illegal month");
            return (NULL);
        }
        if (tm->tm_mday < 1) {
            // int_error(DATAFILE, "illegal day of month");
            return (NULL);
        }
        if (tm->tm_mon > 11) {
            tm->tm_year += tm->tm_mon / 12;
            tm->tm_mon %= 12;
        } {
            int days_in_month;
            while (tm->tm_mday > (days_in_month = (mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365))))) {
                if (++tm->tm_mon == 12) {
                    ++tm->tm_year;
                    tm->tm_mon = 0;
                }
                tm->tm_mday -= days_in_month;
            }
        }
    }
    return (s);
}
Beispiel #4
0
char *
gstrptime(char *s, char *fmt, struct tm *tm)
{
    int yday, date;

    date = yday = 0;
    tm->tm_mday = 1;
    tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
    /* make relative times work (user-defined tic step) */
    tm->tm_year = ZERO_YEAR;

    /* we do not yet calculate wday or yday, so make them illegal
     * [but yday will be read by %j]
     */

    tm->tm_yday = tm->tm_wday = -1;

    while (*fmt) {
        if (*fmt != '%') {
            if (*fmt == ' ') {
                /* space in format means zero or more spaces in input */
                while (*s == ' ')
                    ++s;
                ++fmt;
                continue;
            } else if (*fmt == *s) {
                ++s;
                ++fmt;
                continue;
            } else
                break;		/* literal match has failed */
        }
        /* we are processing a percent escape */

        switch (*++fmt) {
        case 'b':		/* abbreviated month name */
        {
            int m;

            for (m = 0; m < 12; ++m)
                if (strncasecmp(s, abbrev_month_names[m],
                                strlen(abbrev_month_names[m])) == 0) {
                    s += strlen(abbrev_month_names[m]);
                    goto found_abbrev_mon;
                }
            /* get here => not found */
            int_warn(DATAFILE, "Bad abbreviated month name");
            m = 0;
found_abbrev_mon:
            tm->tm_mon = m;
            break;
        }

        case 'B':		/* full month name */
        {
            int m;

            for (m = 0; m < 12; ++m)
                if (strncasecmp(s, full_month_names[m],
                                strlen(full_month_names[m])) == 0) {
                    s += strlen(full_month_names[m]);
                    goto found_full_mon;
                }
            /* get here => not found */
            int_warn(DATAFILE, "Bad full month name");
            m = 0;
found_full_mon:
            tm->tm_mon = m;
            break;
        }

        case 'd':		/* read a day of month */
            s = read_int(s, 2, &tm->tm_mday);
            date++;
            break;

        case 'm':		/* month number */
            s = read_int(s, 2, &tm->tm_mon);
            date++;
            --tm->tm_mon;
            break;

        case 'y':		/* year number */
            s = read_int(s, 2, &tm->tm_year);
            /* In line with the current UNIX98 specification by
             * The Open Group and major Unix vendors,
             * two-digit years 69-99 refer to the 20th century, and
             * values in the range 00-68 refer to the 21st century.
             */
            if (tm->tm_year <= 68)
                tm->tm_year += 100;
            date++;
            tm->tm_year += 1900;
            break;

        case 'Y':
            s = read_int(s, 4, &tm->tm_year);
            date++;
            break;

        case 'j':
            s = read_int(s, 3, &tm->tm_yday);
            tm->tm_yday--;
            date++;
            yday++;
            break;

        case 'H':
            s = read_int(s, 2, &tm->tm_hour);
            break;

        case 'M':
            s = read_int(s, 2, &tm->tm_min);
            break;

        case 'S':
            s = read_int(s, 2, &tm->tm_sec);
            break;

        /* read EPOCH data
         * EPOCH is the std. unixtimeformat seconds since 01.01.1970 UTC
         * actualy i would need a read_long (or what time_t is else)
         *  aktualy this is not my idea       i got if from
         * AlunDa Penguin Jones (21.11.97)
         * but changed %t to %s because of strftime
         * and fixed the localtime() into gmtime()
         * maybe we should use ggmtime() ? but who choose double ????
         * Walter Harms <*****@*****.**> 26 Mar 2000
         */

        case 's':
#if 0 /* HBB 20040213: comment this out, but keep it around for now */
        {
            /* time_t when; */
            int when;
            struct tm *tmwhen;
            s = read_int(s, 10, &when);
            tmwhen = gmtime((time_t*)&when);
            tmwhen->tm_year += 1900;
            *tm = *tmwhen;
            break;
        }
#else
            /* HBB 20040213: New version of this.  64-bit proof and
             * more in line with the rest of this module than the
             * original one. */
        {
            double when;
            /* offset from UNIX epoch (1970) to gnuplot epoch */
            static const long epoch_offset
                = (long)((ZERO_YEAR - 1970) * 365.25) * DAY_SEC;

            when = strtod (s, &s) - epoch_offset;
            ggmtime(tm, when);
            break;
        }
#endif
        default:
            int_warn(DATAFILE, "Bad time format in string");
        }
        fmt++;
    }

    FPRINTF((stderr, "read date-time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));

    /* now check the date/time entered, normalising if necessary
     * read_int cannot read a -ve number, but can read %m=0 then decrement
     * it to -1
     */

#define S (tm->tm_sec)
#define M (tm->tm_min)
#define H (tm->tm_hour)

    if (S >= 60) {
        M += S / 60;
        S %= 60;
    }
    if (M >= 60) {
        H += M / 60;
        M %= 60;
    }
    if (H >= 24) {
        if (yday)
            tm->tm_yday += H / 24;
        tm->tm_mday += H / 24;
        H %= 24;
    }
#undef S
#undef M
#undef H

    FPRINTF((stderr, "normalised time : %02d/%02d/%d:%02d:%02d:%02d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));

    if (date) {
        if (yday) {

            if (tm->tm_yday < 0)
                int_error(DATAFILE, "Illegal day of year");

            /* we just set month to jan, day to yday, and let the
             * normalising code do the work.
             */

            tm->tm_mon = 0;
            /* yday is 0->365, day is 1->31 */
            tm->tm_mday = tm->tm_yday + 1;
        }
        if (tm->tm_mon < 0) {
            int_error(DATAFILE, "illegal month");
            return (NULL);
        }
        if (tm->tm_mday < 1) {
            int_error(DATAFILE, "illegal day of month");
            return (NULL);
        }
        if (tm->tm_mon > 11) {
            tm->tm_year += tm->tm_mon / 12;
            tm->tm_mon %= 12;
        } {
            int days_in_month;
            while (tm->tm_mday > (days_in_month = (mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365))))) {
                if (++tm->tm_mon == 12) {
                    ++tm->tm_year;
                    tm->tm_mon = 0;
                }
                tm->tm_mday -= days_in_month;
            }
        }
    }
    return (s);
}