Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from builtins import object 

2from datetime import datetime 

3from datetime import timedelta 

4 

5__all__ = ["TimeHandler"] 

6 

7 

8class TimeHandler(object): 

9 """Keep track of simulation time information. 

10 

11 This is a class tied to SOCS/Scheduler (OpSim). 

12 Its properties will be reevaluated in the future and this 

13 class may disappear. 

14 

15 Attributes 

16 ---------- 

17 _unix_start : datetime.datetime 

18 Holder for the start of the UNIX epoch 

19 initial_dt : datetime.datetime 

20 The date/time of the simulation start. 

21 current_dt : datetime.datetime 

22 The current simulation date/time. 

23 """ 

24 

25 def __init__(self, initial_date): 

26 """Initialize the class. 

27 

28 Parameters 

29 ---------- 

30 initial_date : str 

31 The inital date in the format of YYYY-MM-DD. 

32 """ 

33 self._unix_start = datetime(1970, 1, 1) 

34 self.initial_dt = datetime.strptime(initial_date, "%Y-%m-%d") 

35 self.current_dt = self.initial_dt 

36 

37 def _time_difference(self, datetime1, datetime2=None): 

38 """Calculate the difference in seconds between two times. 

39 

40 This function calculates the difference in seconds between two given :class:`datetime` instances. If 

41 datetime2 is None, it is assumed to be UNIX epoch start. 

42 

43 Parameters 

44 ---------- 

45 datetime1 : datetime.datetime 

46 The first datetime instance. 

47 datetime2 : datetime.datetime 

48 The second datetime instance. 

49 

50 Returns 

51 ------- 

52 float 

53 The difference in seconds between the two datetime instances. 

54 """ 

55 if datetime2 is None: 

56 datetime2 = self._unix_start 

57 return (datetime1 - datetime2).total_seconds() 

58 

59 @property 

60 def initial_timestamp(self): 

61 """float: Return the UNIX timestamp for the initial date/time. 

62 """ 

63 return self._time_difference(self.initial_dt) 

64 

65 @property 

66 def current_timestamp(self): 

67 """float: Return the UNIX timestamp for the current date/time. 

68 """ 

69 return self._time_difference(self.current_dt) 

70 

71 @property 

72 def current_midnight_timestamp(self): 

73 """float: Return the UNIX timestamp of midnight for the current date. 

74 """ 

75 midnight_dt = datetime(self.current_dt.year, self.current_dt.month, self.current_dt.day) 

76 return self._time_difference(midnight_dt) 

77 

78 @property 

79 def next_midnight_timestamp(self): 

80 """float: Return the UNIX timestamp of midnight for the next day after current date. 

81 """ 

82 midnight_dt = datetime(self.current_dt.year, self.current_dt.month, self.current_dt.day) 

83 midnight_dt += timedelta(**{"days": 1}) 

84 return self._time_difference(midnight_dt) 

85 

86 @property 

87 def time_since_start(self): 

88 """float: The number of seconds since the start date. 

89 """ 

90 return self._time_difference(self.current_dt, self.initial_dt) 

91 

92 def update_time(self, time_increment, time_units): 

93 """Update the currently held timestamp. 

94 

95 This function updates the currently held time with the given increment and corresponding 

96 units. 

97 

98 Parameters 

99 ---------- 

100 time_increment : float 

101 The increment to adjust the current time. 

102 time_units : str 

103 The time unit for the increment value. 

104 """ 

105 time_delta_dict = {time_units: time_increment} 

106 self.current_dt += timedelta(**time_delta_dict) 

107 

108 @property 

109 def current_timestring(self): 

110 """str: Return the ISO-8601 representation of the current date/time. 

111 """ 

112 return self.current_dt.isoformat() 

113 

114 def has_time_elapsed(self, time_span): 

115 """Return a boolean determining if the time span has elapsed. 

116 

117 This function looks to see if the time elapsed (current_time - initial_time) in units of 

118 seconds is greater or less than the requested time span. It will return true if the time span 

119 is greater than or equal the elapsed time and false if less than the elapsed time. 

120 

121 Parameters 

122 ---------- 

123 time_span : float 

124 The requested time span in seconds. 

125 

126 Returns 

127 ------- 

128 bool 

129 True if the time elapsed is greater or False if less than the time span. 

130 """ 

131 return time_span >= self._time_difference(self.current_dt, self.initial_dt) 

132 

133 def future_datetime(self, time_increment, time_units, timestamp=None): 

134 """Return a future datetime object. 

135 

136 This function adds the requested time increment to the current date/time to get a future date/time 

137 and returns a datetime object. An alternative timestamp can be supplied and the time increment will 

138 be applied to that instead. This function does not update the internal timestamp. 

139 

140 Parameters 

141 ---------- 

142 time_increment : float 

143 The increment to adjust the current time. 

144 time_units : str 

145 The time unit for the increment value. 

146 timestamp : float, optional 

147 An alternative timestamp to apply the time increment to. 

148 

149 Returns 

150 ------- 

151 datetime.datetime 

152 The datetime object for the future date/time. 

153 """ 

154 if timestamp is not None: 

155 dt = datetime.utcfromtimestamp(timestamp) 

156 else: 

157 dt = self.current_dt 

158 time_delta_dict = {time_units: time_increment} 

159 return dt + timedelta(**time_delta_dict) 

160 

161 def future_timestamp(self, time_increment, time_units, timestamp=None): 

162 """Return the UNIX timestamp for the future date/time. 

163 

164 This function adds the requested time increment to the current date/time to get a future date/time 

165 and returns the UNIX timestamp for that date/time. It does not update the internal timestamp. 

166 

167 Parameters 

168 ---------- 

169 time_increment : float 

170 The increment to adjust the current time. 

171 time_units : str 

172 The time unit for the increment value. 

173 timestamp : float, optional 

174 An alternative timestamp to apply the time increment to. 

175 

176 Returns 

177 ------- 

178 float 

179 The future UNIX timestamp. 

180 """ 

181 return self._time_difference(self.future_datetime(time_increment, time_units, timestamp=timestamp)) 

182 

183 def future_timestring(self, time_increment, time_units, timestamp=None): 

184 """Return the ISO-8601 representation of the future date/time. 

185 

186 This function adds the requested time increment to the current date/time to get a future date/time 

187 and returns the ISO-8601 formatted string for that date/time. It does not update the internal 

188 timestamp. 

189 

190 Parameters 

191 ---------- 

192 time_increment : float 

193 The increment to adjust the current time. 

194 time_units : str 

195 The time unit for the increment value. 

196 timestamp : float, optional 

197 An alternative timestamp to apply the time increment to. 

198 

199 Returns 

200 ------- 

201 str 

202 The future date/time in ISO-8601. 

203 """ 

204 return self.future_datetime(time_increment, time_units, timestamp=timestamp).isoformat() 

205 

206 def time_since_given(self, timestamp): 

207 """Return the elapsed time (seconds). 

208 

209 This function takes the given timestamp and calculates the elapsed time in seconds 

210 between it and the initial timestamp in the handler. 

211 

212 Parameters 

213 ---------- 

214 timestamp : float 

215 A UNIX timestamp 

216 

217 Returns 

218 ------- 

219 float 

220 The elapsed time (seconds) between the given 

221 """ 

222 dt = datetime.utcfromtimestamp(timestamp) 

223 return self._time_difference(dt, self.initial_dt) 

224 

225 def time_since_given_datetime(self, given_datetime, reverse=False): 

226 """Return the elapsed time (seconds). 

227 

228 This function takes a given datetime object and calculates the elapsed time in seconds 

229 between it and the initial timestamp in the handler. If the given datetime is prior to 

230 the initial timestamp in the handler, use the reverse flag. 

231 

232 Parameters 

233 ---------- 

234 given_datetime : datetime 

235 The given timestamp. 

236 reverse : bool, optional 

237 Flag to make the difference in reverse. Default is False. 

238 

239 Returns 

240 ------- 

241 float 

242 The elapsed time (seconds) between the given timestamp and the initial timestamp 

243 """ 

244 if reverse: 

245 return self._time_difference(self.initial_dt, given_datetime) 

246 else: 

247 return self._time_difference(given_datetime, self.initial_dt)