@@ -158,6 +158,38 @@ array, but rather an ``ExtensionArray``:
158
158
This is the same behavior as ``Series.values`` for categorical data. See
159
159
:ref:`whatsnew_0240.api_breaking.interval_values` for more.
160
160
161
+ .. _whatsnew_0240.enhancements.calendarday:
162
+
163
+ :class:`Day` and associated frequency alias ``'D'`` were documented to represent
164
+ a calendar day; however, arithmetic and operations with :class:`Day` consistently
165
+ respected absolute time (i.e. ```Day(n)`` and acted identically to ```Timedelta(days=n)``).
166
+
167
+ :class:`CalendarDay` and associated frequency alias ``'CD'`` are now available
168
+ and respect calendar day arithmetic. (:issue:`22274`, :issue:`20596`, :issue:`16980`, :issue:`8774`)
169
+
170
+ Addition with :class:`CalendarDay` across a daylight savings time transition:
171
+
172
+ .. ipython:: python
173
+
174
+ ts = pd.Timestamp('2016-10-30 00:00:00', tz='Europe/Helsinki')
175
+ ts + pd.offsets.Day(1)
176
+ ts + pd.offsets.CalendarDay(1)
177
+
178
+ However, if the resulting arithmetic results in a non-existent or ambiguous
179
+ time, and error will raise
180
+
181
+ .. ipython:: python
182
+
183
+ Timestamp("2018-11-03 01:00:00", tz='US/Pacific') + CalendarDay(1)
184
+
185
+ The ``'CD'` frequency alias can be used with :func:`date_range` to create
186
+ a sequence of dates that are separate by a calendar day.
187
+
188
+ .. ipython:: python
189
+
190
+ ts = pd.Timestamp('2016-10-30 00:00:00', tz='Europe/Helsinki')
191
+ pd.date_range(start=ts, freq='CD', periods=3)
192
+ pd.date_range(start=ts, freq='D', periods=3)
161
193
162
194
.. _whatsnew_0240.enhancements.other:
163
195
@@ -283,6 +315,57 @@ that the dates have been converted to UTC
283
315
.. ipython:: python
284
316
pd.to_datetime(["2015-11-18 15:30:00+05:30", "2015-11-18 16:30:00+06:30"], utc=True)
285
317
318
+ .. _whatsnew_0240.api_breaking.calendarday:
319
+
320
+ :class:`Day` and associated frequency alias ``'D'`` were documented to represent
321
+ a calendar day; however, arithmetic and operations with :class:`Day` sometimes
322
+ respected absolute time (i.e. ```Day(n)`` and acted identically to ```Timedelta(days=n)``).
323
+
324
+ *Previous Behavior*:
325
+
326
+ .. code-block:: ipython
327
+
328
+
329
+ In [2]: ts = pd.Timestamp('2016-10-30 00:00:00', tz='Europe/Helsinki')
330
+
331
+ # Respects calendar arithmetic
332
+ In [3]: pd.date_range(start=ts, freq='D', periods=3)
333
+ Out[3]:
334
+ DatetimeIndex(['2016-10-30 00:00:00+03:00', '2016-10-31 00:00:00+02:00',
335
+ '2016-11-01 00:00:00+02:00'],
336
+ dtype='datetime64[ns, Europe/Helsinki]', freq='D')
337
+
338
+ # Respects absolute arithmetic
339
+ In [4]: ts + pd.tseries.frequencies.to_offset('D')
340
+ Out[4]: Timestamp('2016-10-30 23:00:00+0200', tz='Europe/Helsinki')
341
+
342
+ :class:`CalendarDay` and associated frequency alias ``'CD'`` are now available
343
+ and respect calendar day arithmetic. (:issue:`22274`, :issue:`20596`, :issue:`16980`, :issue:`8774`)
344
+
345
+ Addition with :class:`CalendarDay` across a daylight savings time transition:
346
+
347
+ .. ipython:: python
348
+
349
+ ts = pd.Timestamp('2016-10-30 00:00:00', tz='Europe/Helsinki')
350
+ ts + pd.offsets.Day(1)
351
+ ts + pd.offsets.CalendarDay(1)
352
+
353
+ However, if the resulting arithmetic results in a non-existent or ambiguous
354
+ time, and error will raise
355
+
356
+ .. ipython:: python
357
+
358
+ Timestamp("2018-11-03 01:00:00", tz='US/Pacific') + CalendarDay(1)
359
+
360
+ The ``'CD'` frequency alias can be used with :func:`date_range` to create
361
+ a sequence of dates that are separate by a calendar day.
362
+
363
+ .. ipython:: python
364
+
365
+ ts = pd.Timestamp('2016-10-30 00:00:00', tz='Europe/Helsinki')
366
+ pd.date_range(start=ts, freq='CD', periods=3)
367
+ pd.date_range(start=ts, freq='D', periods=3)
368
+
286
369
.. _whatsnew_0240.api_breaking.period_end_time:
287
370
288
371
Time values in ``dt.end_time`` and ``to_timestamp(how='end')``
0 commit comments