TimeRange.allTimes()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 3
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 3
dl 3
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 0
1
#
2
#     SOFTWARE HISTORY
3
#
4
#    Date            Ticket#       Engineer       Description
5
#    ------------    ----------    -----------    --------------------------
6
#    ??/??/??                      xxxxxxxx       Initial Creation.
7
#    01/22/14        2667          bclement       fixed millisecond support
8
#    02/28/14        2667          bclement       constructor can take extra micros for start and end
9
#    06/24/15        4480          dgilling       fix __eq__.
10
#
11
#
12
13
import calendar
14
import datetime
15
import time
16
17
MAX_TIME = 2147483647
18
MICROS_IN_SECOND = 1000000
19
20
21 View Code Duplication
class TimeRange(object):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
22
    def __init__(self, start=None, end=None, startExtraMicros=None, endExtraMicros=None):
23
        self.start = self.__convertToDateTimeWithExtra(start, startExtraMicros)
24
        self.end = self.__convertToDateTimeWithExtra(end, endExtraMicros)
25
26
    def __str__(self):
27
        return self.__repr__()
28
29
    def __repr__(self):
30
        return "(" + self.start.strftime("%b %d %y %H:%M:%S %Z") + ", " + \
31
               self.end.strftime("%b %d %y %H:%M:%S %Z") + ")"
32
33
    def __eq__(self, other):
34
        if not isinstance(self, type(other)):
35
            return False
36
37
        if self.isValid() and other.isValid():
38
            return self.getStart() == other.getStart() and self.getEnd() == other.getEnd()
39
        elif not self.isValid() and not other.isValid():
40
            return True
41
        else:
42
            return False
43
44
    def __ne__(self, other):
45
        return not self.__eq__(other)
46
47
    def __convertToDateTimeWithExtra(self, timeArg, extraMicros):
48
        rval = self.__convertToDateTime(timeArg)
49
        if rval is not None and extraMicros is not None:
50
            rval = rval + datetime.timedelta(microseconds=extraMicros)
51
        return rval
52
53
    def __convertToDateTime(self, timeArg):
54
        if timeArg is None:
55
            return None
56
        if isinstance(timeArg, datetime.datetime):
57
            return timeArg
58
        elif isinstance(timeArg, time.struct_time):
59
            return datetime.datetime(*timeArg[:6])
60
        elif isinstance(timeArg, float):
61
            # seconds as float, should be avoided due to floating point errors
62
            totalSecs = int(timeArg)
63
            micros = int((timeArg - totalSecs) * MICROS_IN_SECOND)
64
            return self.__convertSecsAndMicros(totalSecs, micros)
65
        elif isinstance(timeArg, int):
66
            # seconds as integer
67
            totalSecs = timeArg
68
            return self.__convertSecsAndMicros(totalSecs, 0)
69
        else:
70
            return None
71
72
    def __convertSecsAndMicros(self, seconds, micros):
73
        if seconds < MAX_TIME:
74
            rval = datetime.datetime.utcfromtimestamp(seconds)
75
        else:
76
            extraTime = datetime.timedelta(seconds=(seconds - MAX_TIME))
77
            rval = datetime.datetime.utcfromtimestamp(MAX_TIME) + extraTime
78
        return rval.replace(microsecond=micros)
79
80
    def getStart(self):
81
        return self.start.utctimetuple()
82
83
    def getStartInMillis(self):
84
        return self._getInMillis(self.start)
85
86
    def setStart(self, start, extraMicros=None):
87
        self.start = self.__convertToDateTimeWithExtra(start, extraMicros)
88
89
    def getEnd(self):
90
        return self.end.utctimetuple()
91
92
    def getEndInMillis(self):
93
        return self._getInMillis(self.end)
94
95
    def _getInMillis(self, time):
96
        rval = int(calendar.timegm(time.utctimetuple()) * 1000)
97
        rval += time.microsecond // 1000
98
        return rval
99
100
    def setEnd(self, end, extraMicros=None):
101
        self.end = self.__convertToDateTimeWithExtra(end, extraMicros)
102
103
    def duration(self):
104
        delta = self.end - self.start
105
        return int(delta.total_seconds())
106
107
    def contains(self, timeArg):
108
        if isinstance(timeArg, TimeRange):
109
            if self.duration() == 0:
110
                return self.__eq__(timeArg)
111
            elif timeArg.duration() == 0:
112
                return self.contains(timeArg.start)
113
            return timeArg.start >= self.start and timeArg.end <= self.end
114
        else:
115
            convTime = self.__convertToDateTime(timeArg)
116
            if not isinstance(convTime, datetime.datetime):
117
                raise TypeError("Invalid type for argument time specified to TimeRange.contains().")
118
            if self.duration() != 0:
119
                return self.start <= convTime < self.end
120
            return convTime == self.start
121
122
    def isValid(self):
123
        return bool(self.start != self.end)
124
125
    def overlaps(self, timeRange):
126
        return timeRange.contains(self.start) or self.contains(timeRange.start)
127
128
    def combineWith(self, timeRange):
129
        if self.isValid() and timeRange.isValid():
130
            newStart = min(self.start, timeRange.start)
131
            newEnd = max(self.end, timeRange.end)
132
            return TimeRange(newStart, newEnd)
133
        elif self.isValid():
134
            return self
135
136
        return timeRange
137
138
    @staticmethod
139
    def allTimes():
140
        return TimeRange(0, MAX_TIME)
141