Skip to content

Commit c3910a3

Browse files
committed
ENH: add to_pydatetime methods on Timestamp, DatetimeIndex, close #1372
1 parent 6b53334 commit c3910a3

File tree

3 files changed

+78
-5
lines changed

3 files changed

+78
-5
lines changed

pandas/src/datetime.pyx

+42-5
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,36 @@ try:
4545
except NameError: # py3
4646
basestring = str
4747

48-
def ints_to_pydatetime(ndarray[int64_t] arr):
48+
def ints_to_pydatetime(ndarray[int64_t] arr, tz=None):
4949
cdef:
5050
Py_ssize_t i, n = len(arr)
5151
pandas_datetimestruct dts
5252
ndarray[object] result = np.empty(n, dtype=object)
5353

54-
for i in range(n):
55-
pandas_datetime_to_datetimestruct(arr[i], PANDAS_FR_ns, &dts)
56-
result[i] = datetime(dts.year, dts.month, dts.day,
57-
dts.hour, dts.min, dts.sec, dts.us)
54+
if tz is not None:
55+
if tz is pytz.utc:
56+
for i in range(n):
57+
pandas_datetime_to_datetimestruct(arr[i], PANDAS_FR_ns, &dts)
58+
result[i] = datetime(dts.year, dts.month, dts.day, dts.hour,
59+
dts.min, dts.sec, dts.us, tz)
60+
else:
61+
trans = _get_transitions(tz)
62+
deltas = _get_deltas(tz)
63+
for i in range(n):
64+
# Adjust datetime64 timestamp, recompute datetimestruct
65+
pos = trans.searchsorted(arr[i]) - 1
66+
inf = tz._transition_info[pos]
67+
68+
pandas_datetime_to_datetimestruct(arr[i] + deltas[pos],
69+
PANDAS_FR_ns, &dts)
70+
result[i] = datetime(dts.year, dts.month, dts.day, dts.hour,
71+
dts.min, dts.sec, dts.us,
72+
tz._tzinfos[inf])
73+
else:
74+
for i in range(n):
75+
pandas_datetime_to_datetimestruct(arr[i], PANDAS_FR_ns, &dts)
76+
result[i] = datetime(dts.year, dts.month, dts.day, dts.hour,
77+
dts.min, dts.sec, dts.us)
5878

5979
return result
6080

@@ -163,6 +183,23 @@ class Timestamp(_Timestamp):
163183
return Timestamp(datetime.replace(self, **kwds),
164184
offset=self.offset)
165185

186+
def to_pydatetime(self, warn=True):
187+
"""
188+
If warn=True, issue warning if nanoseconds is nonzero
189+
"""
190+
cdef:
191+
pandas_datetimestruct dts
192+
_TSObject ts
193+
194+
if self.nanosecond != 0 and warn:
195+
print 'Warning: discarding nonzero nanoseconds'
196+
ts = convert_to_tsobject(self, self.tzinfo)
197+
198+
return datetime(ts.dts.year, ts.dts.month, ts.dts.day,
199+
ts.dts.hour, ts.dts.min, ts.dts.sec,
200+
ts.dts.us, ts.tzinfo)
201+
202+
166203
class NaTType(_NaT):
167204

168205
def __new__(cls):

pandas/tseries/index.py

+10
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,16 @@ def _get_object_index(self):
542542
boxed_values = _dt_box_array(self.asi8, self.offset, self.tz)
543543
return Index(boxed_values, dtype=object)
544544

545+
def to_pydatetime(self):
546+
"""
547+
Return DatetimeIndex as object ndarray of datetime.datetime objects
548+
549+
Returns
550+
-------
551+
datetimes : ndarray
552+
"""
553+
return lib.ints_to_pydatetime(self.asi8, tz=self.tz)
554+
545555
def to_period(self, freq=None):
546556
"""
547557
Cast to PeriodIndex at a particular frequency

pandas/tseries/tests/test_timeseries.py

+26
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,32 @@ def test_series_box_timestamp(self):
139139

140140
self.assert_(isinstance(s[5], Timestamp))
141141

142+
def test_timestamp_to_datetime(self):
143+
rng = date_range('20090415', '20090519',
144+
tz='US/Eastern')
145+
146+
stamp = rng[0]
147+
dtval = stamp.to_pydatetime()
148+
self.assertEquals(stamp, dtval)
149+
self.assertEquals(stamp.tzinfo, dtval.tzinfo)
150+
151+
def test_index_convert_to_datetime_array(self):
152+
def _check_rng(rng):
153+
converted = rng.to_pydatetime()
154+
self.assert_(isinstance(converted, np.ndarray))
155+
for x, stamp in zip(converted, rng):
156+
self.assert_(type(x) is datetime)
157+
self.assertEquals(x, stamp.to_pydatetime())
158+
self.assertEquals(x.tzinfo, stamp.tzinfo)
159+
160+
rng = date_range('20090415', '20090519')
161+
rng_eastern = date_range('20090415', '20090519', tz='US/Eastern')
162+
rng_utc = date_range('20090415', '20090519', tz='utc')
163+
164+
_check_rng(rng)
165+
_check_rng(rng_eastern)
166+
_check_rng(rng_utc)
167+
142168
def test_series_ctor_plus_datetimeindex(self):
143169
rng = date_range('20090415', '20090519', freq='B')
144170
data = dict((k, 1) for k in rng)

0 commit comments

Comments
 (0)