|
|
#!/usr/local/midas/bin/python
|
|
|
|
|
|
"""PrecisionTime.py is a collection of python classes to manipulate times with high
|
|
|
precision using integer logic.
|
|
|
|
|
|
Written by "Bill Rideout":mailto:wrideout@haystack.mit.edu May 24, 2007
|
|
|
|
|
|
$Id$
|
|
|
"""
|
|
|
import types
|
|
|
|
|
|
class nsTime:
|
|
|
"""nsTime is a class to handle times given as UT second (integer) and nanosecond (integer)
|
|
|
|
|
|
If nanosecond > 1E9, seconds will be added to second
|
|
|
"""
|
|
|
|
|
|
def __init__(self, second, nanosecond):
|
|
|
self.second = int(second)
|
|
|
if self.second < 0:
|
|
|
raise ValueError('seconds must be greater than 0, not %i' % (self.second))
|
|
|
nanosecond = int(nanosecond)
|
|
|
if nanosecond < 0:
|
|
|
raise ValueError('nanoseconds must be greater 0, not %i' % (nanosecond))
|
|
|
addSec = nanosecond / 1000000000
|
|
|
if addSec > 0:
|
|
|
self.second += addSec
|
|
|
self.nanosecond = nanosecond % 1000000000
|
|
|
self.totalNS = int(self.nanosecond) + int(self.second) * 1000000000
|
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
"""__add__ another nsTime to this one and return a new one as result
|
|
|
"""
|
|
|
nsResult = self.nanosecond + other.nanosecond
|
|
|
addSec = int(nsResult / 1000000000)
|
|
|
newSec = self.second + other.second + addSec
|
|
|
newNS = nsResult % 1000000000
|
|
|
return(nsTime(newSec, newNS))
|
|
|
|
|
|
|
|
|
def increase(self, other):
|
|
|
"""increase adds other to self, changing self (rather than creating a new object)
|
|
|
"""
|
|
|
nsResult = self.nanosecond + other.nanosecond
|
|
|
addSec = int(nsResult / 1000000000)
|
|
|
self.second = self.second + other.second + addSec
|
|
|
self.nanosecond = nsResult % 1000000000
|
|
|
self.totalNS = int(self.nanosecond) + int(self.second) * 1000000000
|
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
"""__sub__ another nsTime from this one and return a new one as result
|
|
|
"""
|
|
|
nsResult = self.nanosecond - other.nanosecond
|
|
|
if nsResult < 0:
|
|
|
addSec = 1
|
|
|
nsResult += 1000000000
|
|
|
else:
|
|
|
addSec = 0
|
|
|
newSec = (self.second - other.second) - addSec
|
|
|
return(nsTime(newSec, nsResult))
|
|
|
|
|
|
|
|
|
def multiply(self, factor):
|
|
|
"""multiply this nsTime times an integer
|
|
|
"""
|
|
|
if type(factor) not in (int, int):
|
|
|
raise ValueError('Illegal type %s passed into nsTime.multiply' % (str(type(factor))))
|
|
|
newTotalNS = self.totalNS * factor
|
|
|
newSeconds = int(newTotalNS / 1000000000)
|
|
|
newNanoseconds = int(newTotalNS - (newSeconds * 1000000000))
|
|
|
return(nsTime(newSeconds, newNanoseconds))
|
|
|
|
|
|
|
|
|
def integerDivision(self, other):
|
|
|
"""integerDivision returns the total number of other nsTimes that fit in self
|
|
|
"""
|
|
|
return(int(self.totalNS / other.totalNS))
|
|
|
|
|
|
def getUnixTime(self):
|
|
|
""" getUnixTime() returns a Unix style time as a float. """
|
|
|
return(float(self.second) + float(self.nanosecond)/1.0e9)
|
|
|
|
|
|
def __mod__(self, other):
|
|
|
"""__mod__ implements self % other.
|
|
|
"""
|
|
|
if type(other) in (int, int):
|
|
|
return self.totalNS % other
|
|
|
else:
|
|
|
return self.totalNS % other.totalNS
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
""" equality of two nsTime objects """
|
|
|
if not (hasattr(other, 'second') and hasattr(other, 'nanosecond')): return False
|
|
|
return self.__cmp__(other) == 0
|
|
|
|
|
|
def __cmp__(self, other):
|
|
|
"""compare two nsTime objects
|
|
|
"""
|
|
|
result = cmp(self.second, other.second)
|
|
|
if result != 0:
|
|
|
return(result)
|
|
|
|
|
|
return(cmp(self.nanosecond, other.nanosecond))
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
return '%d.%09d' % (self.second, self.nanosecond)
|
|
|
|
|
|
|
|
|
class psTime:
|
|
|
"""psTime is a class to handle times given as UT second (integer) and picosecond (integer)
|
|
|
|
|
|
If picosecond > 1E12, seconds will be added to second
|
|
|
"""
|
|
|
|
|
|
def __init__(self, second, picosecond):
|
|
|
self.second = int(second)
|
|
|
if self.second < 0:
|
|
|
raise ValueError('seconds must be greater than 0, not %i' % (self.second))
|
|
|
picosecond = int(picosecond)
|
|
|
if picosecond < 0:
|
|
|
raise ValueError('picoseconds must be greater 0, not %i' % (picosecond))
|
|
|
addSec = picosecond / 1000000000000
|
|
|
if addSec > 0:
|
|
|
self.second += addSec
|
|
|
self.picosecond = picosecond % 1000000000000
|
|
|
self.totalPS = int(self.picosecond) + int(self.second) * 1000000000000
|
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
"""__add__ another psTime to this one and return a new one as result
|
|
|
"""
|
|
|
psResult = self.picosecond + other.picosecond
|
|
|
addSec = int(psResult / 1000000000000)
|
|
|
newSec = self.second + other.second + addSec
|
|
|
newPS = psResult % 1000000000000
|
|
|
return(psTime(newSec, newPS))
|
|
|
|
|
|
|
|
|
def increase(self, other):
|
|
|
"""increase adds other to self, changing self (rather than creating a new object)
|
|
|
"""
|
|
|
psResult = self.picosecond + other.picosecond
|
|
|
addSec = int(psResult / 1000000000000)
|
|
|
self.second = self.second + other.second + addSec
|
|
|
self.picosecond = psResult % 1000000000000
|
|
|
self.totalPS = int(self.picosecond) + int(self.second) * 1000000000000
|
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
"""__sub__ another psTime from this one and return a new one as result
|
|
|
"""
|
|
|
psResult = self.picosecond - other.picosecond
|
|
|
if psResult < 0:
|
|
|
addSec = 1
|
|
|
psResult += 1000000000000
|
|
|
else:
|
|
|
addSec = 0
|
|
|
newSec = (self.second - other.second) - addSec
|
|
|
return(psTime(newSec, psResult))
|
|
|
|
|
|
|
|
|
def multiply(self, factor):
|
|
|
"""multiply this psTime times an integer
|
|
|
"""
|
|
|
if type(factor) not in (int, int):
|
|
|
raise ValueError('Illegal type %s passed into psTime.multiply' % (str(type(factor))))
|
|
|
newTotalPS = self.totalPS * factor
|
|
|
newSeconds = int(newTotalPS / 1000000000000)
|
|
|
newPicoseconds = int(newTotalPS - (newSeconds * 1000000000000))
|
|
|
return(psTime(newSeconds, newPicoseconds))
|
|
|
|
|
|
|
|
|
def integerDivision(self, other):
|
|
|
"""integerDivision returns the total number of other psTimes that fit in self
|
|
|
"""
|
|
|
return(int(self.totalPS / other.totalPS))
|
|
|
|
|
|
def getUnixTime(self):
|
|
|
""" getUnixTime() returns a Unix style time as a float. """
|
|
|
return(float(self.second) + float(self.picosecond)/1.0e12)
|
|
|
|
|
|
def __mod__(self, other):
|
|
|
"""__mod__ implements self % other.
|
|
|
"""
|
|
|
if type(other) in (int, int):
|
|
|
return self.totalPS % other
|
|
|
else:
|
|
|
return self.totalPS % other.totalPS
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
""" equality of two psTime objects """
|
|
|
if not (hasattr(other, 'second') and hasattr(other, 'picosecond')): return False
|
|
|
return self.__cmp__(other) == 0
|
|
|
|
|
|
def __cmp__(self, other):
|
|
|
"""compare two psTime objects
|
|
|
"""
|
|
|
result = cmp(self.second, other.second)
|
|
|
if result != 0:
|
|
|
return(result)
|
|
|
|
|
|
return(cmp(self.picosecond, other.picosecond))
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
return '%d.%12d' % (self.second, self.picosecond)
|
|
|
|
|
|
|