Skip to content

Commit 6a5445d

Browse files
committed
simplify timestamp precision issue
1 parent 52e0171 commit 6a5445d

File tree

4 files changed

+52
-38
lines changed

4 files changed

+52
-38
lines changed

doc/source/whatsnew/v0.23.0.txt

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -780,12 +780,12 @@ Note that this change also applies to :meth:`DataFrame.append`, which has also r
780780
.. _whatsnew_0230.api_breaking.end_time:
781781

782782
Time values in ``dt.end_time`` and ``to_timestamp(how='end')``
783-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
783+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
784784

785-
The time values in ``Period`` and ``PeriodIndex`` objects are now adjusted
786-
appropriately when calling :attr:`Series.dt.end_time`, :attr:`Period.end_time`,
785+
The time values in :class:`Period` and :class:`PeriodIndex` objects are now set
786+
to '23:59:59.999999999' when calling :attr:`Series.dt.end_time`, :attr:`Period.end_time`,
787787
:attr:`PeriodIndex.end_time`, :func:`Period.to_timestamp()` with ``how='end'``,
788-
and :func:`PeriodIndex.to_timestamp()` with ``how='end'`` (:issue:`17157`)
788+
or :func:`PeriodIndex.to_timestamp()` with ``how='end'`` (:issue:`17157`)
789789

790790
Previous Behavior:
791791

@@ -797,22 +797,11 @@ Previous Behavior:
797797
In [4]: pd.Series(p).dt.end_time[0]
798798
Out[4]: Timestamp(2017-01-01 00:00:00)
799799

800-
In [5]: pd.Series(pi).dt.end_time[0]
800+
In [5]: pi.end_time[0]
801801
Out[5]: Timestamp(2017-01-01 00:00:00)
802802

803-
In [6]: p.end_time
804-
Out[6]: Timestamp(2017-01-01 23:59:59.999999999)
805-
806-
In [7]: pi.end_time[0]
807-
Out[7]: Timestamp(2017-01-01 00:00:00)
808-
809-
In [8]: p.to_timestamp(how='end')
810-
Out[8]: Timestamp(2017-01-01 00:00:00)
811-
812-
In [9]: pi.to_timestamp(how='end')[0]
813-
Out[9]: Timestamp(2017-01-01 00:00:00)
814-
815-
Current Behavior
803+
In [6]: pi.to_timestamp(how='end')
804+
Out[6]: Timestamp(2017-01-01 00:00:00)
816805

817806
.. ipython:: python
818807

@@ -821,15 +810,9 @@ Current Behavior
821810

822811
pd.Series(p).dt.end_time[0]
823812

824-
pd.Series(pi).dt.end_time[0]
825-
826-
p.end_time
827-
828813
pi.end_time[0]
829814

830-
p.to_timestamp(how='end')
831-
832-
pi.to_timestamp(how='end')[0]
815+
pi.to_timestamp(how='end')
833816

834817

835818
Build Changes

pandas/core/indexes/datetimes.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,47 @@ def to_julian_date(self):
15661566
DatetimeIndex._add_datetimelike_methods()
15671567

15681568

1569+
<<<<<<< 52e0171b2086c87362ae33db0d3fe9cc2c4afc2a
1570+
=======
1571+
def _generate_regular_range(cls, start, end, periods, freq):
1572+
if isinstance(freq, Tick):
1573+
stride = freq.nanos
1574+
if periods is None:
1575+
b = Timestamp(start).value
1576+
# cannot just use e = Timestamp(end) + 1 because arange breaks when
1577+
# stride is too large, see GH10887
1578+
e = (b + (Timestamp(end).value - b) // stride * stride +
1579+
stride // 2 + 1)
1580+
# end.tz == start.tz by this point due to _generate implementation
1581+
tz = start.tz
1582+
elif start is not None:
1583+
b = Timestamp(start).value
1584+
e = b + np.int64(periods) * stride
1585+
tz = start.tz
1586+
elif end is not None:
1587+
e = Timestamp(end).value + stride
1588+
b = e - np.int64(periods) * stride
1589+
tz = end.tz
1590+
else:
1591+
raise ValueError("at least 'start' or 'end' should be specified "
1592+
"if a 'period' is given.")
1593+
1594+
data = np.arange(b, e, stride, dtype=np.int64)
1595+
# TODO: Do we need to use _simple_new here? just return data.view?
1596+
data = cls._simple_new(data.view(_NS_DTYPE), None, tz=tz)
1597+
else:
1598+
1599+
xdr = generate_range(start=start, end=end,
1600+
periods=periods, offset=offset)
1601+
1602+
dates = list(xdr)
1603+
# utc = len(dates) > 0 and dates[0].tzinfo is not None
1604+
data = tools.to_datetime(dates)
1605+
1606+
return data
1607+
1608+
1609+
>>>>>>> simplify timestamp precision issue
15691610
def date_range(start=None, end=None, periods=None, freq=None, tz=None,
15701611
normalize=False, name=None, closed=None, **kwargs):
15711612
"""

pandas/core/indexes/period.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -519,19 +519,7 @@ def to_timestamp(self, freq=None, how='start'):
519519
base, mult = _gfc(freq)
520520
new_data = self.asfreq(freq, how)
521521

522-
end = how == 'E'
523-
if end:
524-
indexer = np.where(new_data.notnull())
525-
# move forward one period
526-
new_data._values[indexer] += 1
527-
ndarray_vals = new_data._ndarray_values
528-
new_data = period.periodarr_to_dt64arr(ndarray_vals, base)
529-
# subtract one nanosecond
530-
new_data[indexer] -= 1
531-
else:
532-
ndarray_vals = new_data._ndarray_values
533-
new_data = period.periodarr_to_dt64arr(ndarray_vals, base)
534-
522+
new_data = period.periodarr_to_dt64arr(new_data._ndarray_values, base)
535523
return DatetimeIndex(new_data, freq='infer', name=self.name)
536524

537525
@property

pandas/tests/indexes/period/test_period.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,13 @@ def test_periods_number_check(self):
367367
period_range('2011-1-1', '2012-1-1', 'B')
368368

369369
def test_start_time(self):
370+
# GH 17157
370371
index = PeriodIndex(freq='M', start='2016-01-01', end='2016-05-31')
371372
expected_index = date_range('2016-01-01', end='2016-05-31', freq='MS')
372373
tm.assert_index_equal(index.start_time, expected_index)
373374

374375
def test_end_time(self):
376+
# GH 17157
375377
index = PeriodIndex(freq='M', start='2016-01-01', end='2016-05-31')
376378
expected_index = date_range('2016-01-01', end='2016-05-31', freq='M')
377379
expected_index = expected_index.shift(1, freq='D').shift(-1, freq='ns')

0 commit comments

Comments
 (0)