Issue #2667 fixed microseconds floating point error
time ranges now take any extra microseconds as separate argument Former-commit-id:fdf3e42cb7
[formerlyb9bab34f7f
[formerly5b4c234b48
] [formerlyfdf3e42cb7
[formerly 24d9440e440b74f6b1b907062b10da0fef268aed]]] Former-commit-id:b9bab34f7f
[formerly5b4c234b48
] Former-commit-id:b9bab34f7f
Former-commit-id:d26e54bff3
This commit is contained in:
parent
a634576ae3
commit
c813fdcfe1
2 changed files with 41 additions and 17 deletions
|
@ -29,6 +29,7 @@
|
|||
# ------------ ---------- ----------- --------------------------
|
||||
# 09/16/10 dgilling Initial Creation.
|
||||
# 01/22/14 2667 bclement use method to get millis from time range
|
||||
# 02/28/14 2667 bclement deserialize now converts millis to micros
|
||||
#
|
||||
#
|
||||
#
|
||||
|
@ -39,6 +40,8 @@ from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
|
|||
|
||||
ClassAdapter = 'com.raytheon.uf.common.time.TimeRange'
|
||||
|
||||
MICROS_IN_MILLISECOND = 1000
|
||||
MILLIS_IN_SECOND = 1000
|
||||
|
||||
def serialize(context, timeRange):
|
||||
context.writeI64(timeRange.getStartInMillis())
|
||||
|
@ -49,8 +52,12 @@ def deserialize(context):
|
|||
endTime = context.readI64()
|
||||
|
||||
timeRange = TimeRange()
|
||||
timeRange.setStart(startTime/1000.0)
|
||||
timeRange.setEnd(endTime/1000.0)
|
||||
# java uses milliseconds, python uses microseconds
|
||||
startSeconds = startTime // MILLIS_IN_SECOND
|
||||
endSeconds = endTime // MILLIS_IN_SECOND
|
||||
startExtraMicros = (startTime % MILLIS_IN_SECOND) * MICROS_IN_MILLISECOND
|
||||
endExtraMicros = (endTime % MILLIS_IN_SECOND) * MICROS_IN_MILLISECOND
|
||||
timeRange.setStart(startSeconds, startExtraMicros)
|
||||
timeRange.setEnd(endSeconds, endExtraMicros)
|
||||
|
||||
return timeRange
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
# ------------ ---------- ----------- --------------------------
|
||||
# ??/??/?? xxxxxxxx Initial Creation.
|
||||
# 01/22/14 2667 bclement fixed millisecond support
|
||||
# 02/28/14 2667 bclement constructor can take extra micros for start and end
|
||||
#
|
||||
#
|
||||
#
|
||||
|
@ -39,9 +40,9 @@ MAX_TIME = 2147483647
|
|||
MICROS_IN_SECOND = 1000000
|
||||
|
||||
class TimeRange(object):
|
||||
def __init__(self, start=None, end=None):
|
||||
self.start = self.__convertToDateTime(start)
|
||||
self.end = self.__convertToDateTime(end)
|
||||
def __init__(self, start=None, end=None, startExtraMicros=None, endExtraMicros=None):
|
||||
self.start = self.__convertToDateTimeWithExtra(start, startExtraMicros)
|
||||
self.end = self.__convertToDateTimeWithExtra(end, endExtraMicros)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
@ -55,6 +56,12 @@ class TimeRange(object):
|
|||
def __ne__(self, other):
|
||||
return (not self.__eq__(other))
|
||||
|
||||
def __convertToDateTimeWithExtra(self, timeArg, extraMicros):
|
||||
rval = self.__convertToDateTime(timeArg)
|
||||
if rval is not None and extraMicros is not None:
|
||||
rval = rval + datetime.timedelta(microseconds=extraMicros)
|
||||
return rval
|
||||
|
||||
def __convertToDateTime(self, timeArg):
|
||||
if timeArg is None:
|
||||
return None
|
||||
|
@ -62,15 +69,25 @@ class TimeRange(object):
|
|||
return timeArg
|
||||
elif isinstance(timeArg, time.struct_time):
|
||||
return datetime.datetime(*timeArg[:6])
|
||||
else:
|
||||
elif isinstance(timeArg, float):
|
||||
# seconds as float, should be avoided due to floating point errors
|
||||
totalSecs = long(timeArg)
|
||||
micros = int((timeArg - totalSecs) * MICROS_IN_SECOND)
|
||||
if totalSecs < MAX_TIME:
|
||||
rval = datetime.datetime.utcfromtimestamp(totalSecs)
|
||||
else:
|
||||
extraTime = datetime.timedelta(seconds=(totalSecs - MAX_TIME))
|
||||
rval = datetime.datetime.utcfromtimestamp(MAX_TIME) + extraTime
|
||||
return rval.replace(microsecond=micros)
|
||||
return self.__convertSecsAndMicros(totalSecs, micros)
|
||||
elif isinstance(timeArg, (int, long)):
|
||||
# seconds as integer
|
||||
totalSecs = timeArg
|
||||
return self.__convertSecsAndMicros(totalSecs, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __convertSecsAndMicros(self, seconds, micros):
|
||||
if seconds < MAX_TIME:
|
||||
rval = datetime.datetime.utcfromtimestamp(seconds)
|
||||
else:
|
||||
extraTime = datetime.timedelta(seconds=(seconds - MAX_TIME))
|
||||
rval = datetime.datetime.utcfromtimestamp(MAX_TIME) + extraTime
|
||||
return rval.replace(microsecond=micros)
|
||||
|
||||
def getStart(self):
|
||||
return self.start.utctimetuple()
|
||||
|
@ -78,8 +95,8 @@ class TimeRange(object):
|
|||
def getStartInMillis(self):
|
||||
return self._getInMillis(self.start)
|
||||
|
||||
def setStart(self, start):
|
||||
self.start = self.__convertToDateTime(start)
|
||||
def setStart(self, start, extraMicros=None):
|
||||
self.start = self.__convertToDateTimeWithExtra(start, extraMicros)
|
||||
|
||||
def getEnd(self):
|
||||
return self.end.utctimetuple()
|
||||
|
@ -92,8 +109,8 @@ class TimeRange(object):
|
|||
rval += time.microsecond // 1000
|
||||
return rval
|
||||
|
||||
def setEnd(self, end):
|
||||
self.end = self.__convertToDateTime(end)
|
||||
def setEnd(self, end, extraMicros=None):
|
||||
self.end = self.__convertToDateTimeWithExtra(end, extraMicros)
|
||||
|
||||
def duration(self):
|
||||
delta = self.end - self.start
|
||||
|
|
Loading…
Add table
Reference in a new issue