VirtualBox

Ignore:
Timestamp:
Sep 7, 2018 7:59:14 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124922
Message:

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

File:
1 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}
Note: See TracChangeset for help on using the changeset viewer.

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