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