Changeset 74150 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 7, 2018 7:59:14 PM (6 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/time/time.cpp
r74148 r74150 949 949 : g_aiDayOfYear[pTime->u8Month - 1]); 950 950 951 pTime->u8WeekDay = UINT8_MAX; /* later */ 952 951 953 /* 952 954 * The time part. … … 980 982 return NULL; 981 983 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. */ 983 985 if (*pszString == '.') 984 986 { 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); 987 989 if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES) 988 990 return NULL; … … 1016 1018 pszString++; 1017 1019 pTime->fFlags &= ~RTTIME_FLAGS_TYPE_MASK; 1018 pTime->fFlags |= ~RTTIME_FLAGS_TYPE_UTC;1020 pTime->fFlags |= RTTIME_FLAGS_TYPE_UTC; 1019 1021 pTime->offUTC = 0; 1020 1022 } … … 1052 1054 return NULL; 1053 1055 1056 /* Calc week day. */ 1057 rtTimeNormalizeInternal(pTime); 1054 1058 return pTime; 1055 1059 } … … 1183 1187 1184 1188 /* 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); 1191 1193 if ( uWeekDay == RT_MAKE_U32_FROM_U8('m', 'o', 'n', 0)) pTime->u8WeekDay = 0; 1192 1194 else if (uWeekDay == RT_MAKE_U32_FROM_U8('t', 'u', 'e', 0)) pTime->u8WeekDay = 1; … … 1208 1210 return NULL; 1209 1211 } 1212 else if (RT_C_IS_DIGIT(pszString[0])) 1213 pTime->u8WeekDay = UINT8_MAX; 1210 1214 else 1211 1215 return NULL; … … 1221 1225 if (pszString[0] == '\0' || pszString[1] == '\0' || pszString[2] == '\0') 1222 1226 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); 1225 1229 if ( uMonth == RT_MAKE_U32_FROM_U8('j', 'a', 'n', 0)) pTime->u8Month = 1; 1226 1230 else if (uMonth == RT_MAKE_U32_FROM_U8('f', 'e', 'b', 0)) pTime->u8Month = 2; … … 1244 1248 1245 1249 /* Year */ 1250 const char * const pszStartYear = pszString; 1246 1251 rc = RTStrToInt32Ex(pszString, (char **)&pszString, 10, &pTime->i32Year); 1247 1252 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 1248 1261 return NULL; 1249 1262 … … 1296 1309 return NULL; 1297 1310 1298 /* N anoseconds and probably non-standard. */1311 /* Non-standard fraction. Handy for testing, though. */ 1299 1312 if (*pszString == '.') 1300 1313 { 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); 1303 1316 if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS && rc != VWRN_TRAILING_SPACES) 1304 1317 return NULL; … … 1324 1337 else 1325 1338 pTime->u32Nanosecond = 0; 1339 while (RT_C_IS_SPACE(*pszString)) 1340 pszString++; 1326 1341 1327 1342 /* 1328 1343 * Time zone. 1329 1344 */ 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 == '-') 1341 1347 { 1342 1348 if ( !RT_C_IS_DIGIT(pszString[1]) … … 1344 1350 return NULL; 1345 1351 int8_t cUtcHours = (pszString[1] - '0') * 10 + (pszString[2] - '0'); 1346 if (*pszString == '-') 1352 char chSign = *pszString; 1353 if (chSign == '-') 1347 1354 cUtcHours = -cUtcHours; 1348 1355 pszString += 3; … … 1363 1370 if (RT_ABS(pTime->offUTC) > 840) 1364 1371 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 1365 1423 } 1366 1424 /* else: No time zone given, local with offUTC = 0. */ … … 1374 1432 return NULL; 1375 1433 1434 rtTimeNormalizeInternal(pTime); 1376 1435 return pTime; 1377 1436 } -
trunk/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp
r74125 r74150 37 37 #include <iprt/time.h> 38 38 39 #include <iprt/rand.h> 39 40 #include <iprt/test.h> 40 41 #include <iprt/string.h> … … 672 673 szValue, cchResult, a_szExpect, sizeof(a_szExpect) - 1); \ 673 674 } 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) 674 684 SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); 675 685 RTTESTI_CHECK_FMT(RTTimeToRfc2822(&T1, szValue, sizeof(szValue), 0), "Wed, 31 Dec 1969 23:59:58 -0000"); 676 686 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 677 699 SET_TIME(&T1, 2018, 9, 6, 4, 9, 8, 0, 249, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); 678 700 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 680 709 681 710 /*
Note:
See TracChangeset
for help on using the changeset viewer.