VirtualBox

Changeset 74150 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Sep 7, 2018 7:59:14 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/time: Added a few RTTimeFromXxxx tests and fixed bugs found. bugref:9167

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/time/time.cpp

    r74148 r74150  
    949949                         : g_aiDayOfYear[pTime->u8Month - 1]);
    950950
     951    pTime->u8WeekDay = UINT8_MAX; /* later */
     952
    951953    /*
    952954     * The time part.
     
    980982        return NULL;
    981983
    982     /* Just in case there is a fraction of seconds (should be!). */
     984    /* We generally put a 9 digit fraction here, but it's entirely optional. */
    983985    if (*pszString == '.')
    984986    {
    985         const char * const pszStart = pszString;
    986         rc = RTStrToUInt32Ex(pszString + 1, (char **)&pszString, 10, &pTime->u32Nanosecond);
     987        const char * const pszStart = ++pszString;
     988        rc = RTStrToUInt32Ex(pszString, (char **)&pszString, 10, &pTime->u32Nanosecond);
    987989        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
    988990            return NULL;
     
    10161018        pszString++;
    10171019        pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
    1018         pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC;
     1020        pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
    10191021        pTime->offUTC = 0;
    10201022    }
     
    10521054            return NULL;
    10531055
     1056    /* Calc week day. */
     1057    rtTimeNormalizeInternal(pTime);
    10541058    return pTime;
    10551059}
     
    11831187
    11841188    /* Optional day of week: */
    1185     if (RT_C_IS_ALPHA(pszString[0]))
    1186         pTime->u8WeekDay = UINT8_MAX;
    1187     else if (pszString[0] != '\0' && pszString[1] != '\0')
    1188     {
    1189         uint32_t uWeekDay = RT_MAKE_U32_FROM_U8(RT_C_TO_LOWER(pszString[0]), RT_C_TO_LOWER(pszString[0]),
    1190                                                 RT_C_TO_LOWER(pszString[1]), 0);
     1189    if (RT_C_IS_ALPHA(pszString[0]) && pszString[1] != '\0')
     1190    {
     1191        uint32_t uWeekDay = RT_MAKE_U32_FROM_U8(RT_C_TO_LOWER(pszString[0]), RT_C_TO_LOWER(pszString[1]),
     1192                                                RT_C_TO_LOWER(pszString[2]), 0);
    11911193        if (     uWeekDay == RT_MAKE_U32_FROM_U8('m', 'o', 'n', 0))     pTime->u8WeekDay = 0;
    11921194        else if (uWeekDay == RT_MAKE_U32_FROM_U8('t', 'u', 'e', 0))     pTime->u8WeekDay = 1;
     
    12081210            return NULL;
    12091211    }
     1212    else if (RT_C_IS_DIGIT(pszString[0]))
     1213        pTime->u8WeekDay = UINT8_MAX;
    12101214    else
    12111215        return NULL;
     
    12211225    if (pszString[0] == '\0' || pszString[1] == '\0' || pszString[2] == '\0')
    12221226        return NULL;
    1223     uint32_t uMonth = RT_MAKE_U32_FROM_U8(RT_C_TO_LOWER(pszString[0]), RT_C_TO_LOWER(pszString[0]),
    1224                                           RT_C_TO_LOWER(pszString[1]), 0);
     1227    uint32_t uMonth = RT_MAKE_U32_FROM_U8(RT_C_TO_LOWER(pszString[0]), RT_C_TO_LOWER(pszString[1]),
     1228                                          RT_C_TO_LOWER(pszString[2]), 0);
    12251229    if (     uMonth == RT_MAKE_U32_FROM_U8('j', 'a', 'n', 0))     pTime->u8Month = 1;
    12261230    else if (uMonth == RT_MAKE_U32_FROM_U8('f', 'e', 'b', 0))     pTime->u8Month = 2;
     
    12441248
    12451249    /* Year */
     1250    const char * const pszStartYear = pszString;
    12461251    rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->i32Year);
    12471252    if (rc != VWRN_TRAILING_CHARS)
     1253        return NULL;
     1254    if (pszString - pszStartYear >= 4 )
     1255    { /* likely */ }
     1256    else if (pszString - pszStartYear == 3)
     1257        pTime->i32Year += 1900;
     1258    else if (pszString - pszStartYear == 2)
     1259        pTime->i32Year += pTime->i32Year >= 50 ? 1900 : 2000;
     1260    else
    12481261        return NULL;
    12491262
     
    12961309        return NULL;
    12971310
    1298     /* Nanoseconds  and probably non-standard. */
     1311    /* Non-standard fraction.  Handy for testing, though. */
    12991312    if (*pszString == '.')
    13001313    {
    1301         const char * const pszStart = pszString;
    1302         rc = RTStrToUInt32Ex(pszString + 1, (char **)&pszString, 10, &pTime->u32Nanosecond);
     1314        const char * const pszStart = ++pszString;
     1315        rc = RTStrToUInt32Ex(pszString, (char **)&pszString, 10, &pTime->u32Nanosecond);
    13031316        if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES)
    13041317            return NULL;
     
    13241337    else
    13251338        pTime->u32Nanosecond = 0;
     1339    while (RT_C_IS_SPACE(*pszString))
     1340        pszString++;
    13261341
    13271342    /*
    13281343     * Time zone.
    13291344     */
    1330     if (   (pszString[0] == 'G' || pszString[0] == 'g')
    1331         && (pszString[1] == 'M' || pszString[1] == 'm')
    1332         && (pszString[2] == 'T' || pszString[2] == 't') )
    1333     {
    1334         pszString++;
    1335         pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
    1336         pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC;
    1337         pTime->offUTC = 0;
    1338     }
    1339     else if (   *pszString == '+'
    1340              || *pszString == '-')
     1345    if (   *pszString == '+'
     1346        || *pszString == '-')
    13411347    {
    13421348        if (   !RT_C_IS_DIGIT(pszString[1])
     
    13441350            return NULL;
    13451351        int8_t cUtcHours = (pszString[1] - '0') * 10 + (pszString[2] - '0');
    1346         if (*pszString == '-')
     1352        char   chSign    = *pszString;
     1353        if (chSign == '-')
    13471354            cUtcHours = -cUtcHours;
    13481355        pszString += 3;
     
    13631370        if (RT_ABS(pTime->offUTC) > 840)
    13641371            return NULL;
     1372
     1373        /* -0000: GMT isn't necessarily the local time zone, so change flags from local to UTC. */
     1374        if (pTime->offUTC == 0 && chSign == '-')
     1375        {
     1376            pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
     1377            pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
     1378        }
     1379    }
     1380    else if (RT_C_IS_ALPHA(*pszString))
     1381    {
     1382        uint32_t uTimeZone = RT_MAKE_U32_FROM_U8(RT_C_TO_LOWER(pszString[0]), RT_C_TO_LOWER(pszString[1]),
     1383                                                 RT_C_TO_LOWER(pszString[2]), 0);
     1384        if (uTimeZone == RT_MAKE_U32_FROM_U8('g', 'm', 't', 0))
     1385        {
     1386            pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
     1387            pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
     1388            pTime->offUTC = 0;
     1389            pszString += 3;
     1390        }
     1391        else if ((uint16_t)uTimeZone == RT_MAKE_U16('u', 't'))
     1392        {
     1393            pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
     1394            pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC;
     1395            pTime->offUTC = 0;
     1396            pszString += 2;
     1397        }
     1398        else
     1399        {
     1400            static const struct { uint32_t uTimeZone; int32_t offUtc; } s_aLegacyTimeZones[] =
     1401            {
     1402                { RT_MAKE_U32_FROM_U8('e', 'd', 't', 0), -4*60 },
     1403                { RT_MAKE_U32_FROM_U8('e', 's', 't', 0), -5*60 },
     1404                { RT_MAKE_U32_FROM_U8('c', 'd', 't', 0), -5*60 },
     1405                { RT_MAKE_U32_FROM_U8('c', 's', 't', 0), -6*60 },
     1406                { RT_MAKE_U32_FROM_U8('m', 'd', 't', 0), -6*60 },
     1407                { RT_MAKE_U32_FROM_U8('m', 's', 't', 0), -7*60 },
     1408                { RT_MAKE_U32_FROM_U8('p', 'd', 't', 0), -7*60 },
     1409                { RT_MAKE_U32_FROM_U8('p', 's', 't', 0), -8*60 },
     1410            };
     1411            size_t i = RT_ELEMENTS(s_aLegacyTimeZones);
     1412            while (i-- > 0)
     1413                if (s_aLegacyTimeZones[i].uTimeZone == uTimeZone)
     1414                {
     1415                    pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK;
     1416                    pTime->fFlags |= RTTIME_FLAGS_TYPE_LOCAL;
     1417                    pTime->offUTC = s_aLegacyTimeZones[i].offUtc;
     1418                    pszString += 3;
     1419                    break;
     1420                }
     1421        }
     1422
    13651423    }
    13661424    /* else: No time zone given, local with offUTC = 0. */
     
    13741432            return NULL;
    13751433
     1434    rtTimeNormalizeInternal(pTime);
    13761435    return pTime;
    13771436}
  • trunk/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp

    r74125 r74150  
    3737#include <iprt/time.h>
    3838
     39#include <iprt/rand.h>
    3940#include <iprt/test.h>
    4041#include <iprt/string.h>
     
    672673                             szValue, cchResult, a_szExpect, sizeof(a_szExpect) - 1); \
    673674        } while (0)
     675#define RTTESTI_CHECK_FROM(a_FromCall) \
     676        do { \
     677            RTRandBytes(&T2, sizeof(T2)); \
     678            PRTTIME pResult = a_FromCall; \
     679            if (!pResult) \
     680                RTTestFailed(hTest, "%s failed on line " RT_XSTR(__LINE__), #a_FromCall); \
     681            else if (memcmp(&T1, &T2, sizeof(T2)) != 0) \
     682                RTTestFailed(hTest, "%s produced incorrect result on line " RT_XSTR(__LINE__)": %s", #a_FromCall, ToString(&T2)); \
     683        } while (0)
    674684    SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    675685    RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue),                    0), "Wed, 31 Dec 1969 23:59:58 -0000");
    676686    RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), RTTIME_RFC2822_F_GMT), "Wed, 31 Dec 1969 23:59:58 GMT");
     687    RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 0), "1969-12-31T23:59:58Z");
     688    RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 1), "1969-12-31T23:59:58.9Z");
     689    RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 5), "1969-12-31T23:59:58.99999Z");
     690    RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 9), "1969-12-31T23:59:58.999995000Z");
     691    RTTESTI_CHECK_FROM(RTTimeFromString(&T2, "1969-12-31T23:59:58.999995000Z"));
     692    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Wed, 31 Dec 1969 23:59:58.999995 GMT"));
     693    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Wed, 31 Dec 69 23:59:58.999995 GMT"));
     694    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 Dec 69 23:59:58.999995 GMT"));
     695    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 Dec 1969 23:59:58.999995 GMT"));
     696    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "31 dec 1969 23:59:58.999995 GMT"));
     697    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "wEd, 31 Dec 69 23:59:58.999995 UT"));
     698
    677699    SET_TIME(&T1, 2018, 9, 6,  4, 9, 8,        0, 249, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    678700    RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue),                    0), "Thu, 6 Sep 2018 04:09:08 -0000");
    679     RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), RTTIME_RFC2822_F_GMT), "Thu, 6 Sep 2018 04:09:08 GMT");
     701    RTTESTI_CHECK_FMT(RTTimeToStringEx(&T1, szValue, sizeof(szValue), 0), "2018-09-06T04:09:08Z");
     702    RTTESTI_CHECK_FROM(RTTimeFromString(&T2, "2018-09-06T04:09:08Z"));
     703    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 6 Sep 2018 04:09:08 -0000"));
     704    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 6 Sep 2018 04:09:08 GMT"));
     705    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 06 Sep 2018 04:09:08 GMT"));
     706    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, "Thu, 00006 Sep 2018 04:09:08 GMT"));
     707    RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, " 00006 Sep 2018 04:09:08 GMT "));
     708
    680709
    681710    /*
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