@@ -131,21 +131,17 @@ class Timestamp(_Timestamp):
131
131
note: by definition there cannot be any tz info on the ordinal itself """
132
132
return cls (datetime.fromordinal(ordinal),offset = offset,tz = tz)
133
133
134
- def __new__ (cls , object ts_input , object offset = None , tz = None ):
134
+ def __new__ (cls , object ts_input , object offset = None , tz = None , unit = None ):
135
135
cdef _TSObject ts
136
136
cdef _Timestamp ts_base
137
137
138
- if PyFloat_Check(ts_input):
139
- # to do, do we want to support this, ie with fractional seconds?
140
- raise TypeError (" Cannot convert a float to datetime" )
141
-
142
138
if util.is_string_object(ts_input):
143
139
try :
144
140
ts_input = parse_date(ts_input)
145
141
except Exception :
146
142
pass
147
143
148
- ts = convert_to_tsobject(ts_input, tz)
144
+ ts = convert_to_tsobject(ts_input, tz, unit )
149
145
150
146
if ts.value == NPY_NAT:
151
147
return NaT
@@ -311,7 +307,7 @@ class Timestamp(_Timestamp):
311
307
312
308
if self .nanosecond != 0 and warn:
313
309
print ' Warning: discarding nonzero nanoseconds'
314
- ts = convert_to_tsobject(self , self .tzinfo)
310
+ ts = convert_to_tsobject(self , self .tzinfo, None )
315
311
316
312
return datetime(ts.dts.year, ts.dts.month, ts.dts.day,
317
313
ts.dts.hour, ts.dts.min, ts.dts.sec,
@@ -530,7 +526,7 @@ cdef class _Timestamp(datetime):
530
526
cdef:
531
527
pandas_datetimestruct dts
532
528
_TSObject ts
533
- ts = convert_to_tsobject(self , self .tzinfo)
529
+ ts = convert_to_tsobject(self , self .tzinfo, None )
534
530
dts = ts.dts
535
531
return datetime(dts.year, dts.month, dts.day,
536
532
dts.hour, dts.min, dts.sec,
@@ -623,12 +619,13 @@ cpdef _get_utcoffset(tzinfo, obj):
623
619
return tzinfo.utcoffset(obj)
624
620
625
621
# helper to extract datetime and int64 from several different possibilities
626
- cdef convert_to_tsobject(object ts, object tz):
622
+ cdef convert_to_tsobject(object ts, object tz, object unit ):
627
623
"""
628
624
Extract datetime and int64 from any of:
629
- - np.int64
625
+ - np.int64 (with unit providing a possible modifier)
630
626
- np.datetime64
631
- - python int or long object
627
+ - a float (with unit providing a possible modifier)
628
+ - python int or long object (with unit providing a possible modifier)
632
629
- iso8601 string object
633
630
- python datetime object
634
631
- another timestamp object
@@ -647,6 +644,11 @@ cdef convert_to_tsobject(object ts, object tz):
647
644
obj.value = _get_datetime64_nanos(ts)
648
645
pandas_datetime_to_datetimestruct(obj.value, PANDAS_FR_ns, & obj.dts)
649
646
elif is_integer_object(ts):
647
+ ts = ts * cast_from_unit(unit,None )
648
+ obj.value = ts
649
+ pandas_datetime_to_datetimestruct(ts, PANDAS_FR_ns, & obj.dts)
650
+ elif util.is_float_object(ts):
651
+ ts = cast_from_unit(unit,ts)
650
652
obj.value = ts
651
653
pandas_datetime_to_datetimestruct(ts, PANDAS_FR_ns, & obj.dts)
652
654
elif util.is_string_object(ts):
@@ -699,7 +701,7 @@ cdef convert_to_tsobject(object ts, object tz):
699
701
elif PyDate_Check(ts):
700
702
# Keep the converter same as PyDateTime's
701
703
ts = datetime.combine(ts, datetime_time())
702
- return convert_to_tsobject(ts, tz)
704
+ return convert_to_tsobject(ts, tz, None )
703
705
else :
704
706
raise ValueError (" Could not construct Timestamp from argument %s " %
705
707
type (ts))
@@ -804,7 +806,7 @@ def datetime_to_datetime64(ndarray[object] values):
804
806
else :
805
807
inferred_tz = _get_zone(val.tzinfo)
806
808
807
- _ts = convert_to_tsobject(val, None )
809
+ _ts = convert_to_tsobject(val, None , None )
808
810
iresult[i] = _ts.value
809
811
_check_dts_bounds(iresult[i], & _ts.dts)
810
812
else :
@@ -819,7 +821,7 @@ def datetime_to_datetime64(ndarray[object] values):
819
821
820
822
821
823
def array_to_datetime (ndarray[object] values , raise_ = False , dayfirst = False ,
822
- format = None , utc = None , coerce = False ):
824
+ format = None , utc = None , coerce = False , unit = None ):
823
825
cdef:
824
826
Py_ssize_t i, n = len (values)
825
827
object val
@@ -828,6 +830,7 @@ def array_to_datetime(ndarray[object] values, raise_=False, dayfirst=False,
828
830
pandas_datetimestruct dts
829
831
bint utc_convert = bool (utc)
830
832
_TSObject _ts
833
+ int64_t m = cast_from_unit(unit,None )
831
834
832
835
from dateutil.parser import parse
833
836
@@ -841,7 +844,7 @@ def array_to_datetime(ndarray[object] values, raise_=False, dayfirst=False,
841
844
elif PyDateTime_Check(val):
842
845
if val.tzinfo is not None :
843
846
if utc_convert:
844
- _ts = convert_to_tsobject(val, None )
847
+ _ts = convert_to_tsobject(val, None , unit )
845
848
iresult[i] = _ts.value
846
849
_check_dts_bounds(iresult[i], & _ts.dts)
847
850
else :
@@ -861,7 +864,9 @@ def array_to_datetime(ndarray[object] values, raise_=False, dayfirst=False,
861
864
862
865
# if we are coercing, dont' allow integers
863
866
elif util.is_integer_object(val) and not coerce :
864
- iresult[i] = val
867
+ iresult[i] = val* m
868
+ elif util.is_float_object(val) and not coerce :
869
+ iresult[i] = cast_from_unit(unit,val)
865
870
else :
866
871
try :
867
872
if len (val) == 0 :
@@ -1246,6 +1251,31 @@ cdef inline _get_datetime64_nanos(object val):
1246
1251
else :
1247
1252
return ival
1248
1253
1254
+ cdef inline int64_t cast_from_unit(object unit, object ts):
1255
+ """ return a casting of the unit represented to nanoseconds
1256
+ round the fractional part of a float to our precision, p """
1257
+ p = 0
1258
+ if unit == ' s' :
1259
+ m = 1000000000L
1260
+ p = 6
1261
+ elif unit == ' ms' :
1262
+ m = 1000000L
1263
+ p = 3
1264
+ elif unit == ' us' :
1265
+ m = 1000L
1266
+ p = 0
1267
+ else :
1268
+ m = 1L
1269
+
1270
+ # just give me the unit back
1271
+ if ts is None :
1272
+ return m
1273
+
1274
+ # cast the unit, multiply base/frace separately
1275
+ # to avoid precision issues from float -> int
1276
+ base = < int64_t> ts
1277
+ frac = ts- base
1278
+ return < int64_t> (base* m) + < int64_t> (round (frac,p)* m)
1249
1279
1250
1280
def cast_to_nanoseconds (ndarray arr ):
1251
1281
cdef:
@@ -1286,7 +1316,7 @@ def pydt_to_i8(object pydt):
1286
1316
cdef:
1287
1317
_TSObject ts
1288
1318
1289
- ts = convert_to_tsobject(pydt, None )
1319
+ ts = convert_to_tsobject(pydt, None , None )
1290
1320
1291
1321
return ts.value
1292
1322
@@ -1784,7 +1814,7 @@ def get_date_field(ndarray[int64_t] dtindex, object field):
1784
1814
for i in range (count):
1785
1815
if dtindex[i] == NPY_NAT: out[i] = - 1 ; continue
1786
1816
1787
- ts = convert_to_tsobject(dtindex[i], None )
1817
+ ts = convert_to_tsobject(dtindex[i], None , None )
1788
1818
out[i] = ts_dayofweek(ts)
1789
1819
return out
1790
1820
@@ -1793,7 +1823,7 @@ def get_date_field(ndarray[int64_t] dtindex, object field):
1793
1823
if dtindex[i] == NPY_NAT: out[i] = - 1 ; continue
1794
1824
1795
1825
pandas_datetime_to_datetimestruct(dtindex[i], PANDAS_FR_ns, & dts)
1796
- ts = convert_to_tsobject(dtindex[i], None )
1826
+ ts = convert_to_tsobject(dtindex[i], None , None )
1797
1827
isleap = is_leapyear(dts.year)
1798
1828
isleap_prev = is_leapyear(dts.year - 1 )
1799
1829
mo_off = _month_offset[isleap, dts.month - 1 ]
@@ -1831,7 +1861,7 @@ def get_date_field(ndarray[int64_t] dtindex, object field):
1831
1861
1832
1862
1833
1863
cdef inline int m8_weekday(int64_t val):
1834
- ts = convert_to_tsobject(val, None )
1864
+ ts = convert_to_tsobject(val, None , None )
1835
1865
return ts_dayofweek(ts)
1836
1866
1837
1867
cdef int64_t DAY_NS = 86400000000000L L
0 commit comments