[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Improved GM/LOCALTIME_MAX/MIN search



The current Configure code to explore the range of localtime() and gmtime()
isn't portable if time_t is a floating point number as it uses bit shifting on
time_t.

The attached demonstration program will deal with an integer or floating point
time_t.  It runs time_t through difftime() to get a normalized representation
to print.  Merijn, would you please alter the config checks to use this or its
moral equivalent?


-- 
I do have a cause though. It's obscenity. I'm for it.
    - Tom Lehrer

#include <time.h>
#include <stdio.h>

time_t Time_Zero = 0;

void check_gmtime_max (void)
{
    struct tm *date;

    /* Let's not bother checking anything smaller than 2**30-1 */
    time_t time = 1073741823;
    time_t last_time = 0;
    int i;

    for (i = 30; i <= 63; i++) {
        date = gmtime(&time);

        /* gmtime() broke or tm_year overflowed */
        if(date == NULL || date->tm_year < 70)
          break;

        last_time = time;
        time += time + 1;

        /* time_t overflowed */
        if( time < last_time )
            break;
    }

    printf("sGMTIME_max=%.0f\n", difftime(last_time, Time_Zero));
}


void check_gmtime_min (void)
{
    struct tm *date;
    time_t time = -1;
    time_t last_time = 0;
    int i;

    for (i = 1; i <= 63; i++) {
        date = gmtime(&time);

        /* gmtime() broke or tm_year underflowed */
        if(date == NULL || date->tm_year > 69)
            break;

        last_time = time;
        time += time;

        /* time_t underflowed */
        if( time > last_time )
            break;
    }

    printf("sGMTIME_min=%.0f\n", difftime(last_time, Time_Zero));
}


void check_localtime_max (void)
{
    struct tm *date;

    /* Let's not bother checking anything smaller than 2**30-1 */
    time_t time = 1073741823;
    time_t last_time = 0;
    int i;

    for (i = 30; i <= 63; i++) {
        date = localtime(&time);

        /* gmtime() broke or tm_year overflowed */
        if(date == NULL || date->tm_year < 69)
            break;

        last_time = time;
        time += time + 1;

        /* time_t overflowed */
        if( time < last_time )
            break;
    }

    printf("sLOCALTIME_max=%.0f\n", difftime(last_time, Time_Zero));
}


void check_localtime_min (void)
{
    struct tm *date;
    time_t time = -1;
    time_t last_time = 0;
    int i;

    for (i = 1; i <= 63; i++) {
        date = localtime(&time);

        /* gmtime() broke or tm_year underflowed */
        if(date == NULL || date->tm_year > 70)
            break;

        last_time = time;
        time += time;

        /* time_t underflowed */
        if( time > last_time )
            break;
    }

    printf("sLOCALTIME_min=%.0f\n", difftime(last_time, Time_Zero));
}


int main(void) {
    check_gmtime_max();
    check_gmtime_min();
    check_localtime_max();
    check_localtime_min();

    return 0;
}


Follow-Ups from:
"H.Merijn Brand" <h.m.brand@xs4all.nl>
"H.Merijn Brand" <h.m.brand@xs4all.nl>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]