Skip to content

Commit 3c88d19

Browse files
authored
Merge pull request #381 from MIT-LCP/base-datetime
Add base_datetime property
2 parents 327501b + 7998a40 commit 3c88d19

File tree

1 file changed

+89
-43
lines changed

1 file changed

+89
-43
lines changed

wfdb/io/record.py

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,13 @@ class BaseRecord(object):
178178
The counter used at the start of the file.
179179
sig_len : int, optional
180180
The total length of the signal.
181-
base_time : str, optional
182-
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
183-
base_date : str, optional
184-
A string of the record's start date in 'DD/MM/YYYY' format.
181+
base_time : datetime.time, optional
182+
The time of day at the beginning of the record.
183+
base_date : datetime.date, optional
184+
The date at the beginning of the record.
185+
base_datetime : datetime.datetime, optional
186+
The date and time at the beginning of the record, equivalent to
187+
`datetime.combine(base_date, base_time)`.
185188
comments : list, optional
186189
A list of string comments to be written to the header file.
187190
sig_name : str, optional
@@ -200,6 +203,7 @@ def __init__(
200203
sig_len=None,
201204
base_time=None,
202205
base_date=None,
206+
base_datetime=None,
203207
comments=None,
204208
sig_name=None,
205209
):
@@ -209,11 +213,42 @@ def __init__(
209213
self.counter_freq = counter_freq
210214
self.base_counter = base_counter
211215
self.sig_len = sig_len
212-
self.base_time = base_time
213-
self.base_date = base_date
216+
if base_datetime is not None:
217+
if base_time is not None:
218+
raise TypeError(
219+
"cannot specify both base_time and base_datetime"
220+
)
221+
if base_date is not None:
222+
raise TypeError(
223+
"cannot specify both base_date and base_datetime"
224+
)
225+
self.base_datetime = base_datetime
226+
else:
227+
self.base_time = base_time
228+
self.base_date = base_date
214229
self.comments = comments
215230
self.sig_name = sig_name
216231

232+
@property
233+
def base_datetime(self):
234+
if self.base_date is None or self.base_time is None:
235+
return None
236+
else:
237+
return datetime.datetime.combine(
238+
date=self.base_date, time=self.base_time
239+
)
240+
241+
@base_datetime.setter
242+
def base_datetime(self, value):
243+
if value is None:
244+
self.base_date = None
245+
self.base_time = None
246+
elif isinstance(value, datetime.datetime) and value.tzinfo is None:
247+
self.base_date = value.date()
248+
self.base_time = value.time()
249+
else:
250+
raise TypeError(f"invalid base_datetime value: {value!r}")
251+
217252
def check_field(self, field, required_channels="all"):
218253
"""
219254
Check whether a single field is valid in its basic form. Does
@@ -525,12 +560,7 @@ def _adjust_datetime(self, sampfrom):
525560
if sampfrom:
526561
dt_seconds = sampfrom / self.fs
527562
if self.base_date and self.base_time:
528-
self.base_datetime = datetime.datetime.combine(
529-
self.base_date, self.base_time
530-
)
531563
self.base_datetime += datetime.timedelta(seconds=dt_seconds)
532-
self.base_date = self.base_datetime.date()
533-
self.base_time = self.base_datetime.time()
534564
# We can calculate the time even if there is no date
535565
elif self.base_time:
536566
tmp_datetime = datetime.datetime.combine(
@@ -596,10 +626,13 @@ class Record(BaseRecord, _header.HeaderMixin, _signal.SignalMixin):
596626
The counter used at the start of the file.
597627
sig_len : int, optional
598628
The total length of the signal.
599-
base_time : str, optional
600-
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
601-
base_date : str, optional
602-
A string of the record's start date in 'DD/MM/YYYY' format.
629+
base_time : datetime.time, optional
630+
The time of day at the beginning of the record.
631+
base_date : datetime.date, optional
632+
The date at the beginning of the record.
633+
base_datetime : datetime.datetime, optional
634+
The date and time at the beginning of the record, equivalent to
635+
`datetime.combine(base_date, base_time)`.
603636
file_name : str, optional
604637
The name of the file used for analysis.
605638
fmt : list, optional
@@ -656,6 +689,7 @@ def __init__(
656689
sig_len=None,
657690
base_time=None,
658691
base_date=None,
692+
base_datetime=None,
659693
file_name=None,
660694
fmt=None,
661695
samps_per_frame=None,
@@ -677,16 +711,17 @@ def __init__(
677711
# have this field. Even n_seg = 1 makes the header a multi-segment
678712
# header.
679713
super(Record, self).__init__(
680-
record_name,
681-
n_sig,
682-
fs,
683-
counter_freq,
684-
base_counter,
685-
sig_len,
686-
base_time,
687-
base_date,
688-
comments,
689-
sig_name,
714+
record_name=record_name,
715+
n_sig=n_sig,
716+
fs=fs,
717+
counter_freq=counter_freq,
718+
base_counter=base_counter,
719+
sig_len=sig_len,
720+
base_time=base_time,
721+
base_date=base_date,
722+
base_datetime=base_datetime,
723+
comments=comments,
724+
sig_name=sig_name,
690725
)
691726

692727
self.p_signal = p_signal
@@ -896,10 +931,13 @@ class MultiRecord(BaseRecord, _header.MultiHeaderMixin):
896931
The counter used at the start of the file.
897932
sig_len : int, optional
898933
The total length of the signal.
899-
base_time : str, optional
900-
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
901-
base_date : str, optional
902-
A string of the record's start date in 'DD/MM/YYYY' format.
934+
base_time : datetime.time, optional
935+
The time of day at the beginning of the record.
936+
base_date : datetime.date, optional
937+
The date at the beginning of the record.
938+
base_datetime : datetime.datetime, optional
939+
The date and time at the beginning of the record, equivalent to
940+
`datetime.combine(base_date, base_time)`.
903941
seg_name : str, optional
904942
The name of the segment.
905943
seg_len : int, optional
@@ -938,6 +976,7 @@ def __init__(
938976
sig_len=None,
939977
base_time=None,
940978
base_date=None,
979+
base_datetime=None,
941980
seg_name=None,
942981
seg_len=None,
943982
comments=None,
@@ -946,16 +985,17 @@ def __init__(
946985
):
947986

948987
super(MultiRecord, self).__init__(
949-
record_name,
950-
n_sig,
951-
fs,
952-
counter_freq,
953-
base_counter,
954-
sig_len,
955-
base_time,
956-
base_date,
957-
comments,
958-
sig_name,
988+
record_name=record_name,
989+
n_sig=n_sig,
990+
fs=fs,
991+
counter_freq=counter_freq,
992+
base_counter=base_counter,
993+
sig_len=sig_len,
994+
base_time=base_time,
995+
base_date=base_date,
996+
base_datetime=base_datetime,
997+
comments=comments,
998+
sig_name=sig_name,
959999
)
9601000

9611001
self.layout = layout
@@ -2631,6 +2671,7 @@ def wrsamp(
26312671
comments=None,
26322672
base_time=None,
26332673
base_date=None,
2674+
base_datetime=None,
26342675
write_dir="",
26352676
):
26362677
"""
@@ -2674,10 +2715,13 @@ def wrsamp(
26742715
A list of integers specifying the digital baseline.
26752716
comments : list, optional
26762717
A list of string comments to be written to the header file.
2677-
base_time : str, optional
2678-
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
2679-
base_date : str, optional
2680-
A string of the record's start date in 'DD/MM/YYYY' format.
2718+
base_time : datetime.time, optional
2719+
The time of day at the beginning of the record.
2720+
base_date : datetime.date, optional
2721+
The date at the beginning of the record.
2722+
base_datetime : datetime.datetime, optional
2723+
The date and time at the beginning of the record, equivalent to
2724+
setting both `base_date` and `base_time`.
26812725
write_dir : str, optional
26822726
The directory in which to write the files.
26832727
@@ -2735,6 +2779,7 @@ def wrsamp(
27352779
comments=comments,
27362780
base_time=base_time,
27372781
base_date=base_date,
2782+
base_datetime=base_datetime,
27382783
)
27392784
# Compute optimal fields to store the digital signal, carry out adc,
27402785
# and set the fields.
@@ -2753,6 +2798,7 @@ def wrsamp(
27532798
comments=comments,
27542799
base_time=base_time,
27552800
base_date=base_date,
2801+
base_datetime=base_datetime,
27562802
)
27572803
# Use d_signal to set the fields directly
27582804
record.set_d_features()

0 commit comments

Comments
 (0)