- Timestamp:
- Mar 21, 2020 1:01:30 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/common/utils.py
r82968 r83357 1448 1448 return (sTsPrf, sTsIso); 1449 1449 1450 class UtcTzInfo(datetime.tzinfo): 1451 """UTC TZ Info Class""" 1452 def utcoffset(self, _): 1453 return datetime.timedelta(0); 1454 def tzname(self, _): 1455 return "UTC"; 1456 def dst(self, _): 1457 return datetime.timedelta(0); 1458 1459 class GenTzInfo(datetime.tzinfo): 1460 """Generic TZ Info Class""" 1461 def __init__(self, offInMin): 1462 datetime.tzinfo.__init__(self); 1463 self.offInMin = offInMin; 1464 def utcoffset(self, _): 1465 return datetime.timedelta(minutes = self.offInMin); 1466 def tzname(self, _): 1467 if self.offInMin >= 0: 1468 return "+%02d%02d" % (self.offInMin // 60, self.offInMin % 60); 1469 return "-%02d%02d" % (-self.offInMin // 60, -self.offInMin % 60); 1470 def dst(self, _): 1471 return datetime.timedelta(0); 1472 1450 1473 def formatIsoTimestamp(oNow): 1451 1474 """Formats the datetime object as an ISO timestamp.""" 1452 assert oNow.tzinfo is None ;1475 assert oNow.tzinfo is None or isinstance(oNow.tzinfo, UtcTzInfo); 1453 1476 sTs = '%s.%09uZ' % (oNow.strftime('%Y-%m-%dT%H:%M:%S'), oNow.microsecond * 1000); 1454 1477 return sTs; … … 1458 1481 return formatIsoTimestamp(datetime.datetime.utcnow()); 1459 1482 1483 def convertDateTimeToZulu(oDateTime): 1484 """ Converts oDateTime to zulu time if it has timezone info. """ 1485 if oDateTime.tzinfo is not None: 1486 oDateTime = oDateTime.astimezone(UtcTzInfo()); 1487 else: 1488 oDateTime = oDateTime.replace(tzinfo = UtcTzInfo()); 1489 return oDateTime; 1490 1491 def parseIsoTimestamp(sTs): 1492 """ 1493 Parses a typical ISO timestamp, returing a datetime object, reasonably 1494 forgiving, but will throw weird indexing/conversion errors if the input 1495 is malformed. 1496 """ 1497 # YYYY-MM-DD 1498 iYear = int(sTs[0:4]); 1499 assert(sTs[4] == '-'); 1500 iMonth = int(sTs[5:7]); 1501 assert(sTs[7] == '-'); 1502 iDay = int(sTs[8:10]); 1503 1504 # Skip separator 1505 sTime = sTs[10:]; 1506 while sTime[0] in 'Tt \t\n\r': 1507 sTime = sTime[1:]; 1508 1509 # HH:MM:SS 1510 iHour = int(sTime[0:2]); 1511 assert(sTime[2] == ':'); 1512 iMin = int(sTime[3:5]); 1513 assert(sTime[5] == ':'); 1514 iSec = int(sTime[6:8]); 1515 1516 # Fraction? 1517 offTime = 8; 1518 iMicroseconds = 0; 1519 if offTime < len(sTime) and sTime[offTime] in '.,': 1520 offTime += 1; 1521 cchFraction = 0; 1522 while offTime + cchFraction < len(sTime) and sTime[offTime + cchFraction] in '0123456789': 1523 cchFraction += 1; 1524 if cchFraction > 0: 1525 iMicroseconds = int(sTime[offTime : (offTime + cchFraction)]); 1526 offTime += cchFraction; 1527 while cchFraction < 6: 1528 iMicroseconds *= 10; 1529 cchFraction += 1; 1530 while cchFraction > 6: 1531 iMicroseconds = iMicroseconds // 10; 1532 cchFraction -= 1; 1533 1534 # Naive? 1535 if offTime >= len(sTime): 1536 return datetime.datetime(iYear, iMonth, iDay, iHour, iMin, iSec, iMicroseconds); 1537 1538 # Zulu? 1539 if offTime >= len(sTime) or sTime[offTime] in 'Zz': 1540 return datetime.datetime(iYear, iMonth, iDay, iHour, iMin, iSec, iMicroseconds, tzinfo = UtcTzInfo()); 1541 1542 # Some kind of offset afterwards, and strptime is useless. sigh. 1543 if sTime[offTime] in '+-': 1544 chSign = sTime[offTime]; 1545 offTime += 1; 1546 cMinTz = int(sTime[offTime : (offTime + 2)]) * 60; 1547 offTime += 2; 1548 if offTime < len(sTime) and sTime[offTime] in ':': 1549 offTime += 1; 1550 if offTime + 2 <= len(sTime): 1551 cMinTz += int(sTime[offTime : (offTime + 2)]); 1552 offTime += 2; 1553 assert offTime == len(sTime); 1554 if chSign == '-': 1555 cMinTz = -cMinTz; 1556 return datetime.datetime(iYear, iMonth, iDay, iHour, iMin, iSec, iMicroseconds, tzinfo = GenTzInfo(cMinTz)); 1557 assert False, sTs; 1558 return datetime.datetime(iYear, iMonth, iDay, iHour, iMin, iSec, iMicroseconds); 1559 1560 def normalizeIsoTimestampToZulu(sTs): 1561 """ 1562 Takes a iso timestamp string and normalizes it (basically parseIsoTimestamp 1563 + convertDateTimeToZulu + formatIsoTimestamp). 1564 Returns ISO tiemstamp string. 1565 """ 1566 return formatIsoTimestamp(convertDateTimeToZulu(parseIsoTimestamp(sTs))); 1460 1567 1461 1568 def getLocalHourOfWeek(): … … 2232 2339 self.assertEqual(parseIntervalSeconds('1 hour,2m ; 5second'), (3725, None)); 2233 2340 2341 def testZuluNormalization(self): 2342 self.assertEqual(normalizeIsoTimestampToZulu('2011-01-02T03:34:25.000000000Z'), '2011-01-02T03:34:25.000000000Z'); 2343 self.assertEqual(normalizeIsoTimestampToZulu('2011-01-02T03:04:25-0030'), '2011-01-02T03:34:25.000000000Z'); 2344 self.assertEqual(normalizeIsoTimestampToZulu('2011-01-02T03:04:25+0030'), '2011-01-02T02:34:25.000000000Z'); 2345 self.assertEqual(normalizeIsoTimestampToZulu('2020-03-20T20:47:39,832312863+01:00'), '2020-03-20T19:47:39.832312000Z'); 2346 self.assertEqual(normalizeIsoTimestampToZulu('2020-03-20T20:47:39,832312863-02:00'), '2020-03-20T22:47:39.832312000Z'); 2347 2234 2348 def testHasNonAsciiChars(self): 2235 2349 self.assertEqual(hasNonAsciiCharacters(''), False);
Note:
See TracChangeset
for help on using the changeset viewer.