Date

 view release on metacpan or  search on metacpan

clib/tests/time/full.cc  view on Meta::CPAN

                copy1.isdst, (int)tzlocal()->name.length(), tzlocal()->name.data()
            );
            fprintf(stderr,
                "OS: epoch=%li (%04d/%02d/%02d %02d:%02d:%02d %4s %ld) from %04d/%02d/%02d %02d:%02d:%02d DST=%d (%.*s)\n",
                truetime, date2.tm_year+1900, date2.tm_mon+1, date2.tm_mday, date2.tm_hour, date2.tm_min, date2.tm_sec, date2.tm_zone, date2.tm_gmtoff,
                copy2.tm_year+1900, copy2.tm_mon+1, copy2.tm_mday, copy2.tm_hour, copy2.tm_min, copy2.tm_sec, copy2.tm_isdst, (int)tzlocal()->name.length(), tzlocal()->name.data()
            );
            fprintf(stderr, "diff is %lli", (long long)(mytime - truetime));
            return false;
        }
    }

    if (verbose) printf("TESTED %d TIMES\n", cnt);

    return true;
}

static bool test_gmtime    (ptime_t step, ptime_t from, ptime_t till) { return test_forward(step, from, till, "GMT", &panda::time::gmtime, &::gmtime_r); }
static bool test_timegm    (ptime_t step, ptime_t from, ptime_t till) { return test_backward(step, from, till, &panda::time::gmtime, &panda::time::timegm, &::timegm, true); }
static bool test_localtime (ptime_t step, ptime_t from, ptime_t till) { return test_forward(step, from, till, tzlocal()->name, &panda::time::localtime, &::localtime_r); }
// dont test denormalized values (LINUX has bugs with them + when using leap seconds zone, our normalization may differ with OS)
static bool test_timelocal (ptime_t step, ptime_t from, ptime_t till) { return test_backward(step, from, till, &panda::time::localtime, &panda::time::timelocal, &::timelocal, false); }

struct Dia {
    ptime_t step;
    ptime_t from;
    ptime_t till;
};
using Dias = std::vector<Dia>;

TEST_CASE("full-gmtime", "[.]") {
    X64ONLY;
    CHECK(test_gmtime(  299, epoch_from( 2005),       epoch_from(2008,12,30))); // check normal times
    CHECK(test_gmtime(    1, epoch_from( 2004,12,31), epoch_from(2005)));       // check QUAD YEARS threshold
    CHECK(test_gmtime(    1, epoch_from( 1900,12,31), epoch_from(1901)));       // check CENT YEARS threshold
    CHECK(test_gmtime(    1, epoch_from( 2000,12,31), epoch_from(2001)));       // check QUAD CENT YEARS threshold
    CHECK(test_gmtime(86399, epoch_from(-1000),       epoch_from(2014)));       // negative check
    // random check
    CHECK(test_gmtime(0,  1500000000, 1000000));
    CHECK(test_gmtime(0, 20000000000, 1000000));
}

TEST_CASE("full-timegm", "[.]") {
    X64ONLY;
    CHECK(test_timegm( 299, epoch_from(2005),       epoch_from(2008,12,30))); // check normal times
    CHECK(test_timegm(   1, epoch_from(2004,12,31), epoch_from(2005)));       // check QUAD YEARS threshold
    CHECK(test_timegm(   1, epoch_from(1900,12,31), epoch_from(1901)));       // check CENT YEARS threshold
    CHECK(test_timegm(   1, epoch_from(2000,12,31), epoch_from(2001)));       // check QUAD CENT YEARS threshold
    CHECK(test_timegm(9999, epoch_from(1900),       epoch_from(2014)));       // negative check, system's timegm cannot handle 1899-12-31 23:59:59 and earlier
    // random check
    CHECK(test_timegm(0, 200, 200000));
    CHECK(test_timegm(0, 200, 200000));
}

TEST_CASE("full-localtime", "[.]") {
    X64ONLY;
    auto old = tzdir();
    use_system_timezones();

    for (auto tzname : {"Europe/Moscow", "America/New_York", "Australia/Melbourne"}) {
        setenv("TZ", tzname, 1);
        panda::time::tzset();
        ::tzset();

        // check past
        CHECK(test_localtime(39, epoch_from(1879), epoch_from(1881)));
        // check transitions
        CHECK(test_localtime(299, epoch_from(1980), epoch_from(1986)));
        CHECK(test_localtime(299, epoch_from(2000), epoch_from(2006)));
        CHECK(test_localtime(59, epoch_from(2000), epoch_from(2001)));
        // check near future
        CHECK(test_localtime(59, epoch_from(2016), epoch_from(2022)));
        // check far future
        CHECK(test_localtime(299, epoch_from(2060), epoch_from(2066)));
        CHECK(test_localtime(59, epoch_from(2066), epoch_from(2067)));
        // negative check
        CHECK(test_localtime(59, epoch_from(-1000), epoch_from(-999)));
        // random check
        CHECK(test_localtime(0, 1500000000, 1000000));
        CHECK(test_localtime(0, 20000000000, 1000000));
    }

    unsetenv("TZ");
    tzdir(old);
}

TEST_CASE("full-timelocal", "[.]") {
    X64ONLY;
    auto old = tzdir();
    use_system_timezones();

    // Europe/Moscow disabled - system's timelocal has a lot of bugs with non-standart transitions which occur in Moscow
    for (auto tzname : {"America/New_York", "Australia/Melbourne"}) {
        setenv("TZ", tzname, 1);
        panda::time::tzset();
        ::tzset();

        // check past - unavailable, system's timelocal cannot work with these dates
        // check transitions
        CHECK(test_timelocal(86399, epoch_from(1910), epoch_from(1986)));
        CHECK(test_timelocal(3599, epoch_from(1980), epoch_from(1986)));
        CHECK(test_timelocal(3599, epoch_from(2000), epoch_from(2006)));
        CHECK(test_timelocal(3599, epoch_from(2006), epoch_from(2011)));
        // check near future
        CHECK(test_timelocal(3599, epoch_from(2016), epoch_from(2022)));
        // check far future
        CHECK(test_timelocal(3599, epoch_from(2060), epoch_from(2066)));
        // random check
        CHECK(test_timelocal(0, 200, 400000));
    }

    unsetenv("TZ");
    tzdir(old);
}

TEST_CASE("full-leapzone", "[.]") {
    X64ONLY;
    auto old = tzdir();
    use_system_timezones();

    Dias dias = {
        // check past - unavailable, OS's timelocal cannot work with these dates
        // check transitions
        {86399, epoch_from(1910), epoch_from(1970)},
        {3599, epoch_from(1980), epoch_from(1986)},
        {3599, epoch_from(2000), epoch_from(2006)},
        {3599, epoch_from(2006), epoch_from(2011)},
        // check near future
        {3599, epoch_from(2016), epoch_from(2022)},
        // check far future
        {3599, epoch_from(2060), epoch_from(2066)},
        // leap moments
        {1, epoch_from(1981,06,30,12,00,00), epoch_from(1981,07,01,12,00,00)},
        {1, epoch_from(1982,06,30,12,00,00), epoch_from(1982,07,01,12,00,00)},
        {1, epoch_from(1983,06,30,12,00,00), epoch_from(1983,07,01,12,00,00)},
        {1, epoch_from(1985,06,30,12,00,00), epoch_from(1985,07,01,12,00,00)},
        {1, epoch_from(1987,12,31,12,00,00), epoch_from(1988,01,01,12,00,00)},
        {1, epoch_from(1989,12,31,12,00,00), epoch_from(1990,01,01,12,00,00)},
        {1, epoch_from(1990,12,31,12,00,00), epoch_from(1991,01,01,12,00,00)},
        {1, epoch_from(1992,06,30,12,00,00), epoch_from(1992,07,01,12,00,00)},
        {1, epoch_from(1993,06,30,12,00,00), epoch_from(1993,07,01,12,00,00)},
        {1, epoch_from(1994,06,30,12,00,00), epoch_from(1994,07,01,12,00,00)},
        {1, epoch_from(1995,12,31,12,00,00), epoch_from(1996,01,01,12,00,00)},
        {1, epoch_from(1997,06,30,12,00,00), epoch_from(1997,07,01,12,00,00)},
        {1, epoch_from(1998,12,31,12,00,00), epoch_from(1999,01,01,12,00,00)},
        {1, epoch_from(2005,12,31,12,00,00), epoch_from(2006,01,01,12,00,00)},
        {1, epoch_from(2008,12,31,12,00,00), epoch_from(2009,01,01,12,00,00)},
        {1, epoch_from(2012,06,30,12,00,00), epoch_from(2012,07,01,12,00,00)}
    };

    for (auto tzname : {"right/UTC", "right/America/New_York", "right/Australia/Melbourne"}) {
        DYNAMIC_SECTION(tzname) {
            setenv("TZ", tzname, 1);
            panda::time::tzset();
            ::tzset();
            if (tzlocal()->name != tzname) {
                WARN("SKIPPED, leap zone " << tzname << " not found in system");
                continue;
            }

            for (auto& dia : dias) {
                INFO("step=" << dia.step << ", from=" << dia.from << ", till=" << dia.till);
                CHECK(test_localtime(dia.step, dia.from, dia.till));
                CHECK(test_timelocal(dia.step, dia.from, dia.till));
            }

            // random check
            CHECK(test_localtime(0, 1500000000, 5000000));
            CHECK(test_timelocal(0, 120, 1000000));
        }
    }

    unsetenv("TZ");
    tzdir(old);
}

static void test_all_zones (int part) {
    const int parts = 9;
    X64ONLY;
    auto old = tzdir();
    use_system_timezones();

    // many OS have bugs in localtime/timelocal implementations which prevent them from working correctly with listed time zones in our time periods
    std::unordered_set<string> buggy_zones {
        "America/Anchorage", "Australia/Lord_Howe", "America/Scoresbysund", "America/Nome", "Asia/Choibalsan", "Asia/Ust-Nera",
        "Asia/Tehran", "posix/Iran", "posix/Asia/Tehran", "Iran"
    };

    auto tzlist = available_timezones();
    std::sort(tzlist.begin(), tzlist.end(), [](auto a, auto b) { return a < b; });

    for (size_t i = part-1; i < tzlist.size(); i += parts) {
        auto tzname = tzlist[i];
        if (buggy_zones.count(tzname)) continue;
        if (tzname.find("posix") == 0) continue;
        bool leapzone = tzname.find("right") == 0;

        setenv("TZ", tzname.c_str(), 1);
        panda::time::tzset();
        ::tzset();

        DYNAMIC_SECTION(tzname) {
            // check past
            CHECK(test_localtime(3599, epoch_from(1980), epoch_from(1986)));
            CHECK(test_timelocal(3599, epoch_from(1980), epoch_from(1986)));
            // check transitions
            CHECK(test_localtime(3599, epoch_from(2000), epoch_from(2006)));
            CHECK(test_timelocal(3599, epoch_from(2000), epoch_from(2006)));
            // check near future
            CHECK(test_localtime(3599, epoch_from(2016), epoch_from(2022)));
            CHECK(test_timelocal(3599, epoch_from(2016), epoch_from(2022)));

            // check far future
            if (!leapzone) { // skip testing future in leap second zones (OS has bugs)
                CHECK(test_localtime(3599, epoch_from(2060), epoch_from(2066)));
                CHECK(test_timelocal(3599, epoch_from(2060), epoch_from(2066)));
            }
        }
    }

    unsetenv("TZ");
    tzdir(old);
}

TEST_CASE("full-zones-1", "[.]") { test_all_zones(1); }
TEST_CASE("full-zones-2", "[.]") { test_all_zones(2); }
TEST_CASE("full-zones-3", "[.]") { test_all_zones(3); }
TEST_CASE("full-zones-4", "[.]") { test_all_zones(4); }
TEST_CASE("full-zones-5", "[.]") { test_all_zones(5); }
TEST_CASE("full-zones-6", "[.]") { test_all_zones(6); }
TEST_CASE("full-zones-7", "[.]") { test_all_zones(7); }
TEST_CASE("full-zones-8", "[.]") { test_all_zones(8); }
TEST_CASE("full-zones-9", "[.]") { test_all_zones(9); }



( run in 1.698 second using v1.01-cache-2.11-cpan-39bf76dae61 )