@@ -748,8 +748,6 @@ def maybe_infer_to_datetimelike(value, convert_dates=False):
748748 this is pretty strict in that a datetime/timedelta is REQUIRED
749749 in addition to possible nulls/string likes
750750
751- ONLY strings are NOT datetimelike
752-
753751 Parameters
754752 ----------
755753 value : np.array / Series / Index / list-like
@@ -770,64 +768,70 @@ def maybe_infer_to_datetimelike(value, convert_dates=False):
770768 if not is_list_like (v ):
771769 v = [v ]
772770 v = np .array (v , copy = False )
771+
772+ # we only care about object dtypes
773+ if not is_object_dtype (v ):
774+ return value
775+
773776 shape = v .shape
774777 if not v .ndim == 1 :
775778 v = v .ravel ()
776779
777- if len (v ):
778-
779- def _try_datetime (v ):
780- # safe coerce to datetime64
781- try :
782- v = tslib .array_to_datetime (v , errors = 'raise' )
783- except ValueError :
780+ if not len (v ):
781+ return value
784782
785- # we might have a sequence of the same-datetimes with tz's
786- # if so coerce to a DatetimeIndex; if they are not the same,
787- # then these stay as object dtype
788- try :
789- from pandas import to_datetime
790- return to_datetime (v )
791- except :
792- pass
783+ def try_datetime (v ):
784+ # safe coerce to datetime64
785+ try :
786+ v = tslib .array_to_datetime (v , errors = 'raise' )
787+ except ValueError :
793788
789+ # we might have a sequence of the same-datetimes with tz's
790+ # if so coerce to a DatetimeIndex; if they are not the same,
791+ # then these stay as object dtype
792+ try :
793+ from pandas import to_datetime
794+ return to_datetime (v )
794795 except :
795796 pass
796797
797- return v .reshape (shape )
798+ except :
799+ pass
798800
799- def _try_timedelta (v ):
800- # safe coerce to timedelta64
801+ return v .reshape (shape )
801802
802- # will try first with a string & object conversion
803- from pandas import to_timedelta
804- try :
805- return to_timedelta (v )._values .reshape (shape )
806- except :
807- return v
808-
809- # do a quick inference for perf
810- sample = v [:min (3 , len (v ))]
811- inferred_type = lib .infer_dtype (sample )
812-
813- if (inferred_type in ['datetime' , 'datetime64' ] or
814- (convert_dates and inferred_type in ['date' ])):
815- value = _try_datetime (v )
816- elif inferred_type in ['timedelta' , 'timedelta64' ]:
817- value = _try_timedelta (v )
818-
819- # It's possible to have nulls intermixed within the datetime or
820- # timedelta. These will in general have an inferred_type of 'mixed',
821- # so have to try both datetime and timedelta.
822-
823- # try timedelta first to avoid spurious datetime conversions
824- # e.g. '00:00:01' is a timedelta but technically is also a datetime
825- elif inferred_type in ['mixed' ]:
826-
827- if lib .is_possible_datetimelike_array (_ensure_object (v )):
828- value = _try_timedelta (v )
829- if lib .infer_dtype (value ) in ['mixed' ]:
830- value = _try_datetime (v )
803+ def try_timedelta (v ):
804+ # safe coerce to timedelta64
805+
806+ # will try first with a string & object conversion
807+ from pandas import to_timedelta
808+ try :
809+ return to_timedelta (v )._values .reshape (shape )
810+ except :
811+ return v
812+
813+ inferred_type = lib .infer_datetimelike_array (_ensure_object (v ))
814+
815+ if inferred_type == 'date' and convert_dates :
816+ value = try_datetime (v )
817+ elif inferred_type == 'datetime' :
818+ value = try_datetime (v )
819+ elif inferred_type == 'timedelta' :
820+ value = try_timedelta (v )
821+ elif inferred_type == 'nat' :
822+
823+ # if all NaT, return as datetime
824+ if isnull (v ).all ():
825+ value = try_datetime (v )
826+ else :
827+
828+ # We have at least a NaT and a string
829+ # try timedelta first to avoid spurious datetime conversions
830+ # e.g. '00:00:01' is a timedelta but
831+ # technically is also a datetime
832+ value = try_timedelta (v )
833+ if lib .infer_dtype (value ) in ['mixed' ]:
834+ value = try_datetime (v )
831835
832836 return value
833837
0 commit comments