Skip to content

Commit 1a35746

Browse files
committed
ENH: make Period.to_timestamp more flexible, match PeriodIndex.to_timestamp, close #1116
1 parent 4130ca7 commit 1a35746

File tree

2 files changed

+56
-26
lines changed

2 files changed

+56
-26
lines changed

pandas/tseries/period.py

+23-16
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from datetime import datetime
22
import numpy as np
33

4-
from pandas.tseries.frequencies import get_freq_code as _gfc
4+
from pandas.tseries.frequencies import get_freq_code as _gfc, to_offset
55
from pandas.tseries.index import DatetimeIndex, Int64Index
66
from pandas.tseries.tools import parse_time_string
77
import pandas.tseries.frequencies as _freq_mod
88

99
import pandas.core.common as com
10-
import pandas.core.datetools as datetools
1110
from pandas.util import py3compat
1211

1312
from pandas._tseries import Timestamp
@@ -190,31 +189,37 @@ def asfreq(self, freq=None, how='E'):
190189

191190
return Period(new_ordinal, (base2, mult2))
192191

192+
@property
193193
def start_time(self):
194-
return self.to_timestamp(which_end='S')
194+
return self.to_timestamp(how='S')
195195

196+
@property
196197
def end_time(self):
197-
return self.to_timestamp(which_end='E')
198+
return self.to_timestamp(how='E')
198199

199-
def to_timestamp(self, which_end='S'):
200+
def to_timestamp(self, freq='D', how='S'):
200201
"""
201202
Return the Timestamp at the start/end of the period
202203
203204
Parameters
204205
----------
205-
which_end: str, default 'S' (start)
206+
freq : string or DateOffset, default 'D'
207+
Target frequency
208+
how: str, default 'S' (start)
206209
'S', 'E'. Can be aliased as case insensitive
207210
'Start', 'Finish', 'Begin', 'End'
208211
209212
Returns
210213
-------
211214
Timestamp
212215
"""
213-
which_end = _validate_end_alias(which_end)
214-
new_val = self.asfreq('S', which_end)
215-
base, mult = _gfc(new_val.freq)
216-
return Timestamp(lib.period_ordinal_to_dt64(new_val.ordinal, base,
217-
mult))
216+
# how = _validate_end_alias(how)
217+
218+
base, mult = _gfc(freq)
219+
new_val = self.asfreq(freq, how)
220+
new_val = lib.period_ordinal_to_dt64(new_val.ordinal, base, mult)
221+
ts_freq = _period_rule_to_timestamp_rule(self.freq, how=how)
222+
return Timestamp(new_val, offset=to_offset(ts_freq))
218223

219224
year = _period_field_accessor('year')
220225
month = _period_field_accessor('month')
@@ -474,7 +479,7 @@ def __new__(cls, data=None,
474479
if isinstance(freq, Period):
475480
freq = freq.freq
476481
else:
477-
freq = datetools.get_standard_freq(freq)
482+
freq = _freq_mod.get_standard_freq(freq)
478483

479484
if data is None:
480485
subarr, freq = _get_ordinal_range(start, end, periods, freq)
@@ -587,14 +592,16 @@ def map(self, func_to_map):
587592

588593
def _mpl_repr(self):
589594
# how to represent ourselves to matplotlib
590-
return datetools._period_box_array(self, self.freq)
595+
return _period_box_array(self, self.freq)
591596

592597
def to_timestamp(self, freq='D', how='start'):
593598
"""
594-
Cast to datetimeindex of timestamps, at *beginning* of period
599+
Cast to DatetimeIndex
595600
596601
Parameters
597602
----------
603+
freq : string or DateOffset, default 'D'
604+
Target frequency
598605
how : {'s', 'e', 'start', 'end'}
599606
600607
Returns
@@ -657,7 +664,7 @@ def get_value(self, series, key):
657664
return super(PeriodIndex, self).get_value(series, key)
658665
except KeyError:
659666
try:
660-
asdt, parsed, reso = datetools.parse_time_string(key)
667+
asdt, parsed, reso = parse_time_string(key)
661668
grp = _freq_mod._infer_period_group(reso)
662669
freqn = _freq_mod._period_group(self.freq)
663670

@@ -695,7 +702,7 @@ def get_loc(self, key):
695702
return self._engine.get_loc(key)
696703
except KeyError:
697704
try:
698-
asdt, parsed, reso = datetools.parse_time_string(key)
705+
asdt, parsed, reso = parse_time_string(key)
699706
key = asdt
700707
except TypeError:
701708
pass

pandas/tseries/tests/test_period.py

+33-10
Original file line numberDiff line numberDiff line change
@@ -120,28 +120,51 @@ def test_freq_str(self):
120120
self.assertEquals(i2.freq[0], '2')
121121

122122
def test_to_timestamp(self):
123-
intv = Period('1982', freq='A')
124-
start_ts = intv.to_timestamp(which_end='S')
123+
p = Period('1982', freq='A')
124+
start_ts = p.to_timestamp(how='S')
125125
aliases = ['s', 'StarT', 'BEGIn']
126126
for a in aliases:
127-
self.assertEquals(start_ts, intv.to_timestamp(which_end=a))
127+
self.assertEquals(start_ts, p.to_timestamp(how=a))
128128

129-
end_ts = intv.to_timestamp(which_end='E')
129+
end_ts = p.to_timestamp(how='E')
130130
aliases = ['e', 'end', 'FINIsH']
131131
for a in aliases:
132-
self.assertEquals(end_ts, intv.to_timestamp(which_end=a))
132+
self.assertEquals(end_ts, p.to_timestamp(how=a))
133133

134134
from_lst = ['A', 'Q', 'M', 'W', 'B',
135135
'D', 'H', 'Min', 'S']
136136
for i, fcode in enumerate(from_lst):
137-
intv = Period('1982', freq=fcode)
138-
result = intv.to_timestamp().to_period(fcode)
139-
self.assertEquals(result, intv)
137+
p = Period('1982', freq=fcode)
138+
result = p.to_timestamp().to_period(fcode)
139+
self.assertEquals(result, p)
140140

141-
self.assertEquals(intv.start_time(), intv.to_timestamp('S'))
141+
self.assertEquals(p.start_time, p.to_timestamp(how='S'))
142142

143-
self.assertEquals(intv.end_time(), intv.to_timestamp('E'))
143+
self.assertEquals(p.end_time, p.to_timestamp(how='E'))
144144

145+
# Frequency other than daily
146+
147+
p = Period('1985', freq='A')
148+
149+
result = p.to_timestamp('H', how='end')
150+
expected = datetime(1985, 12, 31, 23)
151+
self.assertEquals(result, expected)
152+
153+
result = p.to_timestamp('T', how='end')
154+
expected = datetime(1985, 12, 31, 23, 59)
155+
self.assertEquals(result, expected)
156+
157+
result = p.to_timestamp('S', how='end')
158+
expected = datetime(1985, 12, 31, 23, 59, 59)
159+
self.assertEquals(result, expected)
160+
161+
expected = datetime(1985, 1, 1)
162+
result = p.to_timestamp('H', how='start')
163+
self.assertEquals(result, expected)
164+
result = p.to_timestamp('T', how='start')
165+
self.assertEquals(result, expected)
166+
result = p.to_timestamp('S', how='start')
167+
self.assertEquals(result, expected)
145168

146169
def test_properties_annually(self):
147170
# Test properties on Periods with annually frequency.

0 commit comments

Comments
 (0)