33
44from collections import namedtuple
55from datetime import timedelta
6+ from datetime import datetime
67from csv import writer
78from timeit import default_timer
89from re import compile as re_compile
@@ -26,22 +27,20 @@ def _run(nto):
2627 # pylint: disable=too-many-locals
2728 timedata = []
2829 #cmp_time = re_compile(r'((\d{1,2}):){0,2}(\d{1,2})\s*(?P<AM_PM>[aApP][mM])')
29- # pylint: disable=line-too-long
30- cmp_time = re_compile (r'((?P<hour>\d{1,2})(:(?P<minute>\d{1,2}))?(:(?P<second>\d{1,2}))?\s*(?P<AM_PM>[aApP][mM])?)' )
31- cmp_date = re_compile (r'((?P<year>\d{4})[-/_]?)?(?P<month>\d{1,2})[-/_](?P<day>\d{1,2})' )
30+ reobj = _ReDatetime ()
3231 print (f'NOW: { NOW } ' )
3332 for timestr , expdct in TIMESTRS .items ():
3433 # pylint: disable=too-many-locals
3534 print (f'\n TIMESTR({ timestr } )' )
3635 tic = default_timer ()
37- print ("SEARCH FOR TIME:" , (m := cmp_time .search (timestr )), m .groupdict () if m else '' )
38- print ("SEARCH FOR DATE:" , cmp_date .search (timestr ))
36+ dtre = reobj .search (timestr )
3937 tt0 = timedelta (seconds = default_timer ()- tic )
40- print (f'{ tt0 } re ({ timestr } )' ) # {dta }')
38+ print (f'{ tt0 } re ({ timestr } ) { dtre } ' )
4139
4240 tic = default_timer ()
4341 dta = _get_dt_ampm (timestr , NOW )
4442 assert dta == expdct ['dt' ], f'ACT != EXP\n TXT({ timestr } )\n ACT({ dta } )\n EXP({ expdct ["dt" ]} )'
43+ #assert dta == dtre, f'RE != ME\nTXT({timestr})\nRE({dtre})\nME({dta})'
4544 tta = timedelta (seconds = default_timer ()- tic )
4645 print (f'{ tta } _get_dt_ampm({ timestr } ) { dta } ' )
4746
@@ -82,5 +81,79 @@ def _wr_timedata(fcsv, timedata, nto):
8281 wrobj .writerow (ntd )
8382 print (f' WROTE: { fcsv } ' )
8483
84+
85+ class _ReDatetime :
86+ """Compare custom solution to Python re solution"""
87+ # pylint: disable=too-few-public-methods
88+
89+ # pylint: disable=line-too-long
90+ cmp_time = re_compile (r'((?<![-\d/])(?P<hour>\d{1,2})(?![-\d/])(:(?P<minute>\d{1,2}))?(:(?P<second>\d{1,2}))?\s*(?P<AM_PM>[aApP][mM])?)' )
91+ cmp_date = re_compile (r'((?P<year>\d{4})[-/_]?)?(?P<month>\d{1,2})[-/_](?P<day>\d{1,2})' )
92+
93+ def search (self , timestr ):
94+ """Use Python `re` to search for date and time"""
95+ mtch_time = self ._search_time (timestr )
96+ mtch_date = self ._search_date (timestr )
97+ print ("SEARCH FOR TIME:" , mtch_time , mtch_time .groupdict () if mtch_time else '' )
98+ print ("SEARCH FOR DATE:" , mtch_date , mtch_date .groupdict () if mtch_date else '' )
99+ if mtch_time is None or mtch_time .group ('hour' ) is None :
100+ return None
101+ dct_hms = self ._get_hms (mtch_time )
102+ dct_ymd = self ._get_ymd (mtch_date )
103+ dct = {** dct_ymd , ** dct_hms }
104+ if (m := mtch_time .group ('AM_PM' )) is not None :
105+ if not self ._ampm (dct , m ):
106+ return None
107+ print ("SEARCH DATETIME:" , dct )
108+ if dct :
109+ try :
110+ ret = datetime (year = dct ['year' ], month = dct ['month' ], day = dct ['day' ],
111+ hour = dct ['hour' ],
112+ minute = dct ['minute' ],
113+ second = dct ['second' ])
114+ except ValueError :
115+ print (f'BAD datetime INPUT: { dct } ' )
116+ else :
117+ return ret
118+ return None
119+
120+ def _get_hms (self , mtch ):
121+ return {'hour' : int (mtch .group ('hour' )),
122+ 'minute' : int (m ) if (m := mtch .group ('minute' )) else 0 ,
123+ 'second' : int (m ) if (m := mtch .group ('second' )) else 0 }
124+
125+
126+ def _ampm (self , dct , ampm ):
127+ if ampm is None :
128+ return True
129+ ampm = ampm .upper ()
130+ if ampm == 'PM' :
131+ if 0 <= (hour := dct ['hour' ]) < 12 :
132+ dct ['hour' ] = hour + 12
133+ elif hour != 12 :
134+ return False
135+ else :
136+ assert ampm == 'AM' , dct
137+ if dct ['hour' ] == 12 :
138+ dct ['hour' ] = 0
139+ return True
140+
141+ def _get_ymd (self , mtch ):
142+ if mtch :
143+ return {'year' : int (m ) if (m := mtch .group ('year' )) else NOW .year ,
144+ 'month' : int (m ) if (m := mtch .group ('month' )) else NOW .month ,
145+ 'day' : int (m ) if (m := mtch .group ('day' )) else NOW .day }
146+ return {'year' : NOW .year ,
147+ 'month' : NOW .month ,
148+ 'day' : NOW .day }
149+
150+ def _search_time (self , timestr ):
151+ """Use Python re to search for time"""
152+ return self .cmp_time .search (timestr )
153+
154+ def _search_date (self , timestr ):
155+ """Use Python re to search for time"""
156+ return self .cmp_date .search (timestr )
157+
85158if __name__ == '__main__' :
86159 test_tt_getdt ()
0 commit comments