@@ -249,6 +249,105 @@ def base_datetime(self, value):
249249 else :
250250 raise TypeError (f"invalid base_datetime value: { value !r} " )
251251
252+ def get_frame_number (self , time_value ):
253+ """
254+ Convert a time value to a frame number.
255+
256+ A time value may be specified as:
257+ - An integer or floating-point number, representing the number of
258+ WFDB frames elapsed from the start of the record.
259+ - A `datetime.timedelta` object, representing elapsed time from the
260+ start of the record.
261+ - A `datetime.datetime` object, representing an absolute date and
262+ time (if the record starting time is known.)
263+
264+ Note that this function may return a value that is less than zero
265+ or greater than the actual length of the record.
266+
267+ Parameters
268+ ----------
269+ time_value : number or timedelta or datetime
270+ A time value.
271+
272+ Returns
273+ -------
274+ frame_number : float
275+ Frame number (possibly a fractional frame number).
276+
277+ """
278+ if hasattr (time_value , "__float__" ):
279+ return float (time_value )
280+
281+ if isinstance (time_value , datetime .datetime ):
282+ if not self .base_datetime :
283+ raise ValueError (
284+ "base_datetime is unknown; cannot convert absolute "
285+ "date/time to a frame number"
286+ )
287+ time_value -= self .base_datetime
288+
289+ if isinstance (time_value , datetime .timedelta ):
290+ return time_value .total_seconds () * self .fs
291+
292+ raise TypeError (f"invalid time value: { time_value !r} " )
293+
294+ def get_elapsed_time (self , time_value ):
295+ """
296+ Convert a time value to an elapsed time in seconds.
297+
298+ A time value may be specified as:
299+ - An integer or floating-point number, representing the number of
300+ WFDB frames elapsed from the start of the record.
301+ - A `datetime.timedelta` object, representing elapsed time from the
302+ start of the record.
303+ - A `datetime.datetime` object, representing an absolute date and
304+ time (if the record starting time is known.)
305+
306+ Parameters
307+ ----------
308+ time_value : number or timedelta or datetime
309+ A time value.
310+
311+ Returns
312+ -------
313+ elapsed_time : timedelta
314+ Elapsed time from the start of the record.
315+
316+ """
317+ time_value = self .get_frame_number (time_value )
318+ return datetime .timedelta (seconds = time_value / self .fs )
319+
320+ def get_absolute_time (self , time_value ):
321+ """
322+ Convert a time value to an absolute date and time.
323+
324+ A time value may be specified as:
325+ - An integer or floating-point number, representing the number of
326+ WFDB frames elapsed from the start of the record.
327+ - A `datetime.timedelta` object, representing elapsed time from the
328+ start of the record.
329+ - A `datetime.datetime` object, representing an absolute date and
330+ time (if the record starting time is known.)
331+
332+ Parameters
333+ ----------
334+ time_value : number or timedelta or datetime
335+ A time value.
336+
337+ Returns
338+ -------
339+ absolute_time : datetime
340+ Absolute date and time.
341+
342+ """
343+ time_value = self .get_elapsed_time (time_value )
344+ if not self .base_datetime :
345+ raise ValueError (
346+ "base_datetime is unknown; cannot convert frame number "
347+ "to an absolute date/time"
348+ )
349+ return time_value + self .base_datetime
350+
252351 def check_field (self , field , required_channels = "all" ):
253352 """
254353 Check whether a single field is valid in its basic form. Does
0 commit comments