VirtualBox

Changeset 5974 in vbox


Ignore:
Timestamp:
Dec 6, 2007 2:43:18 AM (17 years ago)
Author:
vboxsync
Message:

Implemented RTTimeNormalize. Added a offUTC field to RTTIME (only partly implemented). Made RTTimeToString/RTTimeSpecToString print offUTC for local times (it incorrectly printed Z for them).

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/time.h

    r5605 r5974  
    550550    /** Flags, of the RTTIME_FLAGS_* \#defines. */
    551551    uint32_t    fFlags;
    552 /** @todo we need a UTC offset field. */
     552    /** UCT time offset in minutes (-840-840).
     553     * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
     554    int32_t     offUTC;
    553555} RTTIME;
    554556#pragma pack()
     
    578580 * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
    579581#define RTTIME_FLAGS_COMMON_YEAR    RT_BIT(7)
     582/** The mask of valid flags. */
     583#define RTTIME_FLAGS_MASK           UINT32_C(0xff)
    580584/** @} */
    581585
     
    615619
    616620/**
    617  * Normalizes the fields of a timestructure.
    618  *
    619  * It is possible to calculate month/day fields in some
    620  * combinations. It's also possible to overflow other
    621  * fields, and these overflows will be adjusted for.
     621 * Normalizes the fields of a time structure.
     622 *
     623 * It is possible to calculate year-day from month/day and vice
     624 * versa. If you adjust any of of these, make sure to zero the
     625 * other so you make it clear which of the fields to use. If
     626 * it's ambiguous, the year-day field is used (and you get
     627 * assertions in debug builds).
     628 *
     629 * All the time fields and the year-day or month/day fields will
     630 * be adjusted for overflows. (Since all fields are unsigned, there
     631 * is no underflows.) It is possible to exploit this for simple
     632 * date math, though the recommended way of doing that to implode
     633 * the time into a timespec and do the math on that.
    622634 *
    623635 * @returns pTime on success.
    624636 * @returns NULL if the data is invalid.
     637 *
    625638 * @param   pTime       The time structure to normalize.
     639 *
     640 * @remarks This function doesn't work with local time, only with UTC time.
    626641 */
    627642RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
     
    655670 */
    656671RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
     672
     673/**
     674 * Normalizes the fields of a time structure containing local time.
     675 *
     676 * See RTTimeNormalize for details.
     677 *
     678 * @returns pTime on success.
     679 * @returns NULL if the data is invalid.
     680 * @param   pTime       The time structure to normalize.
     681 */
     682RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
    657683
    658684/**
  • trunk/src/VBox/Runtime/common/time/time.cpp

    r5408 r5974  
    293293
    294294    /* weekday - 1970-01-01 was a Thursday (3) */
    295     pTime->u8WeekDay     = (uint32_t)(i32Div + 3) % 7;
     295    pTime->u8WeekDay     = ((int)(i32Div % 7) + 3 + 7) % 7;
    296296
    297297    /*
     
    332332    i32Div -= paiDayOfYear[iMonth];
    333333    pTime->u8MonthDay    = i32Div + 1;
     334
     335    /* This is for UTC timespecs, so, no offset. */
     336    pTime->offUTC        = 0;
    334337
    335338    return pTime;
     
    389392
    390393/**
    391  * Normalizes the fields of a timestructure.
    392  *
    393  * It is possible to calculate month/day fields in some
    394  * combinations. It's also possible to overflow other
    395  * fields, and these overflows will be adjusted for.
     394 * Internal worker for RTTimeNormalize and RTTimeLocalNormalize.
     395 * It doesn't adjust the UCT offset but leaves that for RTTimeLocalNormalize.
     396 */
     397PRTTIME rtTimeNormalizeInternal(PRTTIME pTime)
     398{
     399    /*
     400     * Fix the YearDay and Month/MonthDay.
     401     */
     402    bool fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
     403    if (!pTime->u16YearDay)
     404    {
     405        /*
     406         * The Month+MonthDay must present, overflow adjust them and calc the year day.
     407         */
     408        AssertMsgReturn(    pTime->u8Month
     409                        &&  pTime->u8MonthDay,
     410                        ("date=%d-%d-%d\n", pTime->i32Year, pTime->u8Month, pTime->u8MonthDay),
     411                        NULL);
     412        while (pTime->u8Month > 12)
     413        {
     414            pTime->u8Month -= 12;
     415            pTime->i32Year++;
     416            fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
     417            pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
     418        }
     419
     420        for (;;)
     421        {
     422            unsigned cDaysInMonth = fLeapYear
     423                                  ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
     424                                  : g_acDaysInMonthsLeap[pTime->u8Month - 1];
     425            if (pTime->u8MonthDay <= cDaysInMonth)
     426                break;
     427            pTime->u8MonthDay -= cDaysInMonth;
     428            if (pTime->u8Month != 12)
     429                pTime->u8Month++;
     430            else
     431            {
     432                pTime->u8Month = 1;
     433                pTime->i32Year++;
     434                fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
     435                pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
     436            }
     437        }
     438
     439        pTime->u16YearDay  = pTime->u8MonthDay - 1
     440                           + (fLeapYear
     441                              ? g_aiDayOfYearLeap[pTime->u8Month - 1]
     442                              : g_aiDayOfYear[pTime->u8Month - 1]);
     443    }
     444    else
     445    {
     446        /*
     447         * Are both YearDay and Month/MonthDay valid?
     448         * Check that they don't overflow and match, if not use YearDay (simpler).
     449         */
     450        bool fRecalc = true;
     451        if (    pTime->u8Month
     452            &&  pTime->u8MonthDay)
     453        {
     454            do
     455            {
     456                /* If you change one, zero the other to make clear what you mean. */
     457                AssertBreak(pTime->u8Month <= 12,);
     458                AssertBreak(pTime->u8MonthDay <= (fLeapYear
     459                                                  ? g_acDaysInMonthsLeap[pTime->u8Month - 1]
     460                                                  : g_acDaysInMonths[pTime->u8Month - 1]),);
     461                uint16_t u16YearDay = pTime->u8MonthDay - 1
     462                                    + (fLeapYear
     463                                       ? g_aiDayOfYearLeap[pTime->u8Month - 1]
     464                                       : g_aiDayOfYear[pTime->u8Month - 1]);
     465                AssertBreak(u16YearDay == pTime->u16YearDay, );
     466                fRecalc = false;
     467            } while (0);
     468        }
     469        if (fRecalc)
     470        {
     471            /* overflow adjust YearDay */
     472            while (pTime->u16YearDay > (fLeapYear ? 366 : 365))
     473            {
     474                pTime->u16YearDay -= fLeapYear ? 366 : 365;
     475                pTime->i32Year++;
     476                fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
     477                pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
     478            }
     479
     480            /* calc Month and MonthDay */
     481            const uint16_t *paiDayOfYear = fLeapYear
     482                                         ? &g_aiDayOfYearLeap[0]
     483                                         : &g_aiDayOfYear[0];
     484            pTime->u8Month = 1;
     485            while (pTime->u16YearDay > paiDayOfYear[pTime->u8Month])
     486                pTime->u8Month++;
     487            Assert(pTime->u8Month >= 1 && pTime->u8Month <= 12);
     488            pTime->u8MonthDay = pTime->u16YearDay - paiDayOfYear[pTime->u8Month - 1] + 1;
     489        }
     490    }
     491
     492    /*
     493     * Fixup time overflows.
     494     * Use unsigned int values internally to avoid overflows.
     495     */
     496    unsigned uSecond = pTime->u8Second;
     497    unsigned uMinute = pTime->u8Minute;
     498    unsigned uHour   = pTime->u8Hour;
     499
     500    while (pTime->u32Nanosecond >= 1000000000)
     501    {
     502        pTime->u32Nanosecond -= 1000000000;
     503        uSecond++;
     504    }
     505
     506    while (uSecond >= 60)
     507    {
     508        uSecond -= 60;
     509        uMinute++;
     510    }
     511
     512    while (uMinute >= 60)
     513    {
     514        uMinute -= 60;
     515        uHour++;
     516    }
     517
     518    while (uHour >= 24)
     519    {
     520        uHour -= 24;
     521
     522        /* This is really a RTTimeIncDay kind of thing... */
     523        if (pTime->u16YearDay + 1 != (fLeapYear ? g_aiDayOfYearLeap[pTime->u8Month] : g_aiDayOfYear[pTime->u8Month]))
     524        {
     525            pTime->u16YearDay++;
     526            pTime->u8MonthDay++;
     527        }
     528        else if (pTime->u8Month != 12)
     529        {
     530            pTime->u16YearDay++;
     531            pTime->u8Month++;
     532            pTime->u8MonthDay = 1;
     533        }
     534        else
     535        {
     536            pTime->i32Year++;
     537            fLeapYear = rtTimeIsLeapYear(pTime->i32Year);
     538            pTime->fFlags &= ~(RTTIME_FLAGS_COMMON_YEAR | RTTIME_FLAGS_LEAP_YEAR);
     539            pTime->u16YearDay = 1;
     540            pTime->u8Month = 1;
     541            pTime->u8MonthDay = 1;
     542        }
     543    }
     544
     545    pTime->u8Second = uSecond;
     546    pTime->u8Minute = uMinute;
     547    pTime->u8Hour = uHour;
     548
     549    /*
     550     * Correct the leap year flag.
     551     * Assert if it's wrong, but ignore if unset.
     552     */
     553    if (fLeapYear)
     554    {
     555        Assert(!(pTime->fFlags & RTTIME_FLAGS_COMMON_YEAR));
     556        pTime->fFlags &= ~RTTIME_FLAGS_COMMON_YEAR;
     557        pTime->fFlags |= RTTIME_FLAGS_LEAP_YEAR;
     558    }
     559    else
     560    {
     561        Assert(!(pTime->fFlags & RTTIME_FLAGS_LEAP_YEAR));
     562        pTime->fFlags &= ~RTTIME_FLAGS_LEAP_YEAR;
     563        pTime->fFlags |= RTTIME_FLAGS_COMMON_YEAR;
     564    }
     565
     566
     567    /*
     568     * Calc week day.
     569     *
     570     * 1970-01-01 was a Thursday (3), so find the number of days relative to
     571     * that point. We use the table when possible and a slow+stupid+brute-force
     572     * algorithm for points outside it. Feel free to optimize the latter by
     573     * using some clever formula.
     574     */
     575#if 1
     576    if (    pTime->i32Year >= OFF_YEAR_IDX_0_YEAR
     577        &&  pTime->i32Year <  OFF_YEAR_IDX_0_YEAR + RT_ELEMENTS(g_aoffYear))
     578    {
     579        int32_t offDays = g_aoffYear[pTime->i32Year - OFF_YEAR_IDX_0_YEAR]
     580                        + pTime->u16YearDay -1;
     581        pTime->u8WeekDay = ((offDays % 7) + 3 + 7) % 7;
     582    }
     583    else
     584#endif
     585    {
     586        int32_t i32Year = pTime->i32Year;
     587        if (i32Year >= 1970)
     588        {
     589            uint64_t offDays = pTime->u16YearDay - 1;
     590            while (--i32Year >= 1970)
     591                offDays += rtTimeIsLeapYear(i32Year) ? 366 : 365;
     592            pTime->u8WeekDay = (uint8_t)((offDays + 3) % 7);
     593        }
     594        else
     595        {
     596            int64_t offDays = (fLeapYear ? -366 - 1 : -365 - 1) + pTime->u16YearDay;
     597            while (++i32Year < 1970)
     598                offDays -= rtTimeIsLeapYear(i32Year) ? 366 : 365;
     599            pTime->u8WeekDay = ((int)(offDays % 7) + 3 + 7) % 7;
     600        }
     601    }
     602    return pTime;
     603}
     604
     605
     606/**
     607 * Normalizes the fields of a time structure.
     608 *
     609 * It is possible to calculate year-day from month/day and vice
     610 * versa. If you adjust any of of these, make sure to zero the
     611 * other so you make it clear which of the fields to use. If
     612 * it's ambiguous, the year-day field is used (and you get
     613 * assertions in debug builds).
     614 *
     615 * All the time fields and the year-day or month/day fields will
     616 * be adjusted for overflows. (Since all fields are unsigned, there
     617 * is no underflows.) It is possible to exploit this for simple
     618 * date math, though the recommended way of doing that to implode
     619 * the time into a timespec and do the math on that.
    396620 *
    397621 * @returns pTime on success.
    398622 * @returns NULL if the data is invalid.
     623 *
    399624 * @param   pTime       The time structure to normalize.
     625 *
     626 * @remarks This function doesn't work with local time, only with UTC time.
    400627 */
    401628RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime)
    402629{
    403     /** @todo  */
    404     return NULL;
     630    /*
     631     * Validate that we've got the minium of stuff handy.
     632     */
     633    AssertReturn(VALID_PTR(pTime), NULL);
     634    AssertMsgReturn(!(pTime->fFlags & ~RTTIME_FLAGS_MASK), ("%#x\n", pTime->fFlags), NULL);
     635    AssertMsgReturn((pTime->fFlags & RTTIME_FLAGS_TYPE_MASK) != RTTIME_FLAGS_TYPE_LOCAL, ("Use RTTimeLocalNormalize!\n"), NULL);
     636    AssertMsgReturn(pTime->offUTC == 0, ("%d; Use RTTimeLocalNormalize!\n", pTime->offUTC), NULL);
     637
     638    pTime = rtTimeNormalizeInternal(pTime);
     639    if (pTime)
     640        pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
     641    return pTime;
    405642}
    406643
     
    417654RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb)
    418655{
    419     size_t cch = RTStrPrintf(psz, cb, "%RI32-%02u-%02uT%02u:%02u:%02u.%09RU32Z",
    420                              pTime->i32Year, pTime->u8Month, pTime->u8MonthDay,
    421                              pTime->u8Hour, pTime->u8Minute, pTime->u8Second, pTime->u32Nanosecond);
    422     if (    cch <= 1
    423         ||  psz[cch - 1] != 'Z')
    424         return NULL;
     656    /* (Default to UTC if not specified) */
     657    if (    (pTime->fFlags & RTTIME_FLAGS_TYPE_MASK) == RTTIME_FLAGS_TYPE_LOCAL
     658        &&  pTime->offUTC)
     659    {
     660        Assert(pTime->offUTC <= 840 && pTime->offUTC >= -840);
     661        int32_t offUTCHour   = pTime->offUTC / 60;
     662        int32_t offUTCMinute = pTime->offUTC % 60;
     663        char chSign;
     664        if (pTime->offUTC >= 0)
     665            chSign = '+';
     666        else
     667        {
     668            chSign = '-';
     669            offUTCMinute = -offUTCMinute;
     670            offUTCHour = -offUTCHour;
     671        }
     672        size_t cch = RTStrPrintf(psz, cb,
     673                                 "%RI32-%02u-%02uT%02u:%02u:%02u.%09RU32%c%02%02",
     674                                 pTime->i32Year, pTime->u8Month, pTime->u8MonthDay,
     675                                 pTime->u8Hour, pTime->u8Minute, pTime->u8Second, pTime->u32Nanosecond,
     676                                 chSign, offUTCHour, offUTCMinute);
     677        if (    cch <= 15
     678            ||  psz[cch - 5] != chSign)
     679            return NULL;
     680    }
     681    else
     682    {
     683        size_t cch = RTStrPrintf(psz, cb, "%RI32-%02u-%02uT%02u:%02u:%02u.%09RU32Z",
     684                                 pTime->i32Year, pTime->u8Month, pTime->u8MonthDay,
     685                                 pTime->u8Hour, pTime->u8Minute, pTime->u8Second, pTime->u32Nanosecond);
     686        if (    cch <= 15
     687            ||  psz[cch - 1] != 'Z')
     688            return NULL;
     689    }
    425690    return psz;
    426691}
  • trunk/src/VBox/Runtime/generic/RTTimeLocalDeltaNano-generic.cpp

    • Property snv:keyword deleted
    • Property svn:keywords set to Id
    r4071 r5974  
    1 /* $Id: RTAssertDoBreakpoint-generic.cpp 18670 2007-02-15 19:49:19Z bird $ */
     1/* $Id$ */
    22/** @file
    33 * innotek Portable Runtime - Time, generic RTTimeLocalDeltaNano.
  • trunk/src/VBox/Runtime/generic/RTTimeLocalExplode-generic.cpp

    r4071 r5974  
    1 /* $Id $ */
     1/* $Id: $ */
    22/** @file
    33 * innotek Portable Runtime - Time, generic RTTimeLocalExplode.
     
    2727    pTime = RTTimeExplode(pTime, pTimeSpec);
    2828    if (pTime)
     29    {
    2930        pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
     31        pTime->offZone = RTTimeLocalDeltaNano() / (UINT64_C(1000000000)*3600); /** @todo this is obviosly wrong. Need RTTimeLocalDeltaNanoFor(pTimeSpec); */
     32    }
    3033    return pTime;
    3134}
  • trunk/src/VBox/Runtime/testcase/tstTimeSpec.cpp

    r4071 r5974  
    3030{
    3131    static char szBuf[128];
    32     RTStrPrintf(szBuf, sizeof(szBuf), "%04d-%02d-%02dT%02u-%02u-%02u.%09u [YD%u WD%u F%#x]",
     32    RTStrPrintf(szBuf, sizeof(szBuf), "%04d-%02d-%02dT%02u:%02u:%02u.%09u [YD%u WD%u UO%d F%#x]",
    3333                pTime->i32Year,
    3434                pTime->u8Month,
     
    4040                pTime->u16YearDay,
    4141                pTime->u8WeekDay,
     42                pTime->offUTC,
    4243                pTime->fFlags);
    4344    return szBuf;
     
    5354        { \
    5455            RTPrintf("tstTimeSpec: FAILURE - %RI64 != %RI64\n", RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1)); \
    55             return 1; \
     56            RTPrintf("             line no %d\n", __LINE__); \
     57            cErrors++; \
    5658        } \
    5759    } while (0)
     
    6466        { \
    6567            RTPrintf("tstTimeSpec: FAILURE - %RI64 != %RI64\n", RTTimeSpecGetNano(&Ts2), RTTimeSpecGetNano(&Ts1)); \
    66             return 1; \
     68            RTPrintf("             line no %d\n", __LINE__); \
     69            cErrors++; \
    6770        } \
    6871    } while (0)
    6972
    70 #define CHECK_TIME(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _fFlags)\
     73#define CHECK_TIME(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags)\
    7174    do { \
    7275        if (    (pTime)->i32Year != (_i32Year) \
     
    7982            ||  (pTime)->u8Second != (_u8Second) \
    8083            ||  (pTime)->u32Nanosecond != (_u32Nanosecond) \
     84            ||  (pTime)->offUTC != (_offUTC) \
    8185            ||  (pTime)->fFlags != (_fFlags) \
    8286            ) \
    8387        { \
    8488            RTPrintf("tstTimeSpec: FAILURE - %s\n" \
    85                      "                    != %04d-%02d-%02dT%02u-%02u-%02u.%09u [YD%u WD%u F%#x]\n", \
     89                     "                    != %04d-%02d-%02dT%02u-%02u-%02u.%09u [YD%u WD%u UO%d F%#x]\n", \
    8690                     ToString(pTime), (_i32Year), (_u8Month), (_u8MonthDay), (_u8Hour), (_u8Minute), \
    87                      (_u8Second), (_u32Nanosecond), (_u16YearDay), (_u8WeekDay), (_fFlags)); \
    88             return 1; \
     91                     (_u8Second), (_u32Nanosecond), (_u16YearDay), (_u8WeekDay), (_offUTC), (_fFlags)); \
     92            RTPrintf("             line no %d\n", __LINE__); \
     93            cErrors++; \
    8994        } \
     95        else \
     96            RTPrintf("          => %s\n", ToString(pTime)); \
     97    } while (0)
     98
     99#define SET_TIME(pTime, _i32Year, _u8Month, _u8MonthDay, _u8Hour, _u8Minute, _u8Second, _u32Nanosecond, _u16YearDay, _u8WeekDay, _offUTC, _fFlags)\
     100    do { \
     101        (pTime)->i32Year = (_i32Year); \
     102        (pTime)->u8Month = (_u8Month); \
     103        (pTime)->u8WeekDay = (_u8WeekDay); \
     104        (pTime)->u16YearDay = (_u16YearDay); \
     105        (pTime)->u8MonthDay = (_u8MonthDay); \
     106        (pTime)->u8Hour = (_u8Hour); \
     107        (pTime)->u8Minute = (_u8Minute); \
     108        (pTime)->u8Second = (_u8Second); \
     109        (pTime)->u32Nanosecond = (_u32Nanosecond); \
     110        (pTime)->offUTC = (_offUTC); \
     111        (pTime)->fFlags = (_fFlags); \
     112        RTPrintf("tstTimeSpec: %s\n", ToString(pTime)); \
    90113    } while (0)
    91114
     
    93116int main()
    94117{
     118    unsigned    cErrors = 0;
    95119    RTTIMESPEC  Now;
    96120    RTTIMESPEC  Ts1;
    97121    RTTIMESPEC  Ts2;
    98122    RTTIME      T1;
    99     //RTTIME      T2;
     123    RTTIME      T2;
    100124
    101125    /*
     
    109133    {
    110134        RTPrintf("tstTimeSpec: FAILURE - %RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));
    111         return 1;
     135        cErrors++;
    112136    }
    113137
     
    122146    {
    123147        RTPrintf("tstTimeSpec: FAILURE - %RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));
    124         return 1;
     148        cErrors++;
    125149    }
    126150
     
    129153     */
    130154    TEST_NS(INT64_C(0));
    131     CHECK_TIME(&T1, 1970,01,01, 00,00,00,        0,   1, 3, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     155    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    132156    TEST_NS(INT64_C(86400000000000));
    133     CHECK_TIME(&T1, 1970,01,02, 00,00,00,        0,   2, 4, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     157    CHECK_TIME(&T1, 1970,01,02, 00,00,00,        0,   2, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    134158
    135159    TEST_NS(INT64_C(1));
    136     CHECK_TIME(&T1, 1970,01,01, 00,00,00,        1,   1, 3, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     160    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        1,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    137161    TEST_NS(INT64_C(-1));
    138     CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     162    CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    139163
    140164    /*
     
    144168    TEST_NS(INT64_MIN);
    145169    TEST_SEC(1095379198);
    146     CHECK_TIME(&T1, 2004, 9,16, 23,59,58,        0, 260, 3, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     170    CHECK_TIME(&T1, 2004, 9,16, 23,59,58,        0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    147171    TEST_SEC(1095379199);
    148     CHECK_TIME(&T1, 2004, 9,16, 23,59,59,        0, 260, 3, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     172    CHECK_TIME(&T1, 2004, 9,16, 23,59,59,        0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    149173    TEST_SEC(1095379200);
    150     CHECK_TIME(&T1, 2004, 9,17, 00,00,00,        0, 261, 4, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     174    CHECK_TIME(&T1, 2004, 9,17, 00,00,00,        0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    151175    TEST_SEC(1095379201);
    152     CHECK_TIME(&T1, 2004, 9,17, 00,00,01,        0, 261, 4, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    153 
    154 
    155 
    156     RTPrintf("tstTimeSpec: SUCCESS\n");
    157     return 0;
     176    CHECK_TIME(&T1, 2004, 9,17, 00,00,01,        0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     177
     178
     179    /*
     180     * Test normalization (UTC).
     181     */
     182    /* simple */
     183    CHECK_NZ(RTTimeNow(&Now));
     184    CHECK_NZ(RTTimeExplode(&T1, &Now));
     185    T2 = T1;
     186    CHECK_NZ(RTTimeNormalize(&T1));
     187    if (memcmp(&T1, &T2, sizeof(T1)))
     188    {
     189        RTPrintf("tstTimeSpec: FAILURE - simple normalization failed\n");
     190        cErrors++;
     191    }
     192    CHECK_NZ(RTTimeImplode(&Ts1, &T1));
     193    CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now));
     194
     195    /* a few partial dates. */
     196    memset(&T1, 0, sizeof(T1));
     197    SET_TIME(  &T1, 1970,01,01, 00,00,00,        0,   0, 0, 0, 0);
     198    CHECK_NZ(RTTimeNormalize(&T1));
     199    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     200
     201    SET_TIME(  &T1, 1970,00,00, 00,00,00,        1,   1, 0, 0, 0);
     202    CHECK_NZ(RTTimeNormalize(&T1));
     203    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        1,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     204
     205    SET_TIME(  &T1, 2007,12,06, 02,15,23,        1,   0, 0, 0, 0);
     206    CHECK_NZ(RTTimeNormalize(&T1));
     207    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     208
     209    SET_TIME(  &T1, 1968,01,30, 00,19,24,        5,   0, 0, 0, 0);
     210    CHECK_NZ(RTTimeNormalize(&T1));
     211    CHECK_TIME(&T1, 1968,01,30, 00,19,24,        5,  30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     212
     213    SET_TIME(  &T1, 1969,01,31, 00, 9, 2,        7,   0, 0, 0, 0);
     214    CHECK_NZ(RTTimeNormalize(&T1));
     215    CHECK_TIME(&T1, 1969,01,31, 00, 9, 2,        7,  31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     216
     217    SET_TIME(  &T1, 1969,03,31, 00, 9, 2,        7,   0, 0, 0, 0);
     218    CHECK_NZ(RTTimeNormalize(&T1));
     219    CHECK_TIME(&T1, 1969,03,31, 00, 9, 2,        7,  90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     220
     221    SET_TIME(  &T1, 1969,12,31, 00,00,00,        9,   0, 0, 0, 0);
     222    CHECK_NZ(RTTimeNormalize(&T1));
     223    CHECK_TIME(&T1, 1969,12,31, 00,00,00,        9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     224
     225    SET_TIME(  &T1, 1969,12,30, 00,00,00,       30,   0, 0, 0, 0);
     226    CHECK_NZ(RTTimeNormalize(&T1));
     227    CHECK_TIME(&T1, 1969,12,30, 00,00,00,       30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     228
     229    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 363, 0, 0, 0);
     230    CHECK_NZ(RTTimeNormalize(&T1));
     231    CHECK_TIME(&T1, 1969,12,29, 00,00,00,       30, 363, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     232
     233    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 362, 6, 0, 0);
     234    CHECK_NZ(RTTimeNormalize(&T1));
     235    CHECK_TIME(&T1, 1969,12,28, 00,00,00,       30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     236
     237    SET_TIME(  &T1, 1969,12,27, 00,00,00,       30,   0, 5, 0, 0);
     238    CHECK_NZ(RTTimeNormalize(&T1));
     239    CHECK_TIME(&T1, 1969,12,27, 00,00,00,       30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     240
     241    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 360, 0, 0, 0);
     242    CHECK_NZ(RTTimeNormalize(&T1));
     243    CHECK_TIME(&T1, 1969,12,26, 00,00,00,       30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     244
     245    SET_TIME(  &T1, 1969,12,25, 00,00,00,       12,   0, 0, 0, 0);
     246    CHECK_NZ(RTTimeNormalize(&T1));
     247    CHECK_TIME(&T1, 1969,12,25, 00,00,00,       12, 359, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     248
     249    SET_TIME(  &T1, 1969,12,24, 00,00,00,       16,   0, 0, 0, 0);
     250    CHECK_NZ(RTTimeNormalize(&T1));
     251    CHECK_TIME(&T1, 1969,12,24, 00,00,00,       16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     252
     253    /* outside the year table range */
     254    SET_TIME(  &T1, 1200,01,30, 00,00,00,        2,   0, 0, 0, 0);
     255    CHECK_NZ(RTTimeNormalize(&T1));
     256    CHECK_TIME(&T1, 1200,01,30, 00,00,00,        2,  30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     257
     258    SET_TIME(  &T1, 2555,11,29, 00,00,00,        2,   0, 0, 0, 0);
     259    CHECK_NZ(RTTimeNormalize(&T1));
     260    CHECK_TIME(&T1, 2555,11,29, 00,00,00,        2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     261
     262    SET_TIME(  &T1, 2555,00,00, 00,00,00,        3, 333, 0, 0, 0);
     263    CHECK_NZ(RTTimeNormalize(&T1));
     264    CHECK_TIME(&T1, 2555,11,29, 00,00,00,        3, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     265
     266    /* time overflow */
     267    SET_TIME(  &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 0, 0);
     268    CHECK_NZ(RTTimeNormalize(&T1));
     269    CHECK_TIME(&T1, 1970,01, 9, 19,19,19,294967295,   9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     270
     271    /* date overflow */
     272    SET_TIME(  &T1, 2007,11,36, 02,15,23,        1,   0, 0, 0, 0);
     273    CHECK_NZ(RTTimeNormalize(&T1));
     274    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     275
     276    SET_TIME(  &T1, 2007,10,67, 02,15,23,        1,   0, 0, 0, 0);
     277    CHECK_NZ(RTTimeNormalize(&T1));
     278    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     279
     280    SET_TIME(  &T1, 2007,10,98, 02,15,23,        1,   0, 0, 0, 0);
     281    CHECK_NZ(RTTimeNormalize(&T1));
     282    CHECK_TIME(&T1, 2008,01,06, 02,15,23,        1,   6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     283
     284    SET_TIME(  &T1, 2006,24,06, 02,15,23,        1,   0, 0, 0, 0);
     285    CHECK_NZ(RTTimeNormalize(&T1));
     286    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     287
     288    SET_TIME(  &T1, 2003,60,37, 02,15,23,        1,   0, 0, 0, 0);
     289    CHECK_NZ(RTTimeNormalize(&T1));
     290    CHECK_TIME(&T1, 2008,01,06, 02,15,23,        1,   6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
     291
     292    SET_TIME(  &T1, 2003,00,00, 02,15,23,        1,1801, 0, 0, 0);
     293    CHECK_NZ(RTTimeNormalize(&T1));
     294    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
     295
     296    /*
     297     * Summary
     298     */
     299    if (!cErrors)
     300        RTPrintf("tstTimeSpec: SUCCESS\n");
     301    else
     302        RTPrintf("tstTimeSpec: FAILURE - %d errors\n", cErrors);
     303    return cErrors ? 1 : 0;
    158304}
    159305
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette