Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pandas/_libs/tslibs/conversion.pxd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from cpython.datetime cimport datetime
from cpython.datetime cimport datetime, tzinfo

from numpy cimport int64_t, int32_t
from numpy cimport int64_t, int32_t, ndarray

from pandas._libs.tslibs.np_datetime cimport npy_datetimestruct

Expand All @@ -24,3 +24,5 @@ cdef int64_t get_datetime64_nanos(object val) except? -1

cpdef datetime localize_pydatetime(datetime dt, object tz)
cdef int64_t cast_from_unit(object ts, str unit) except? -1

cpdef ndarray[int64_t] normalize_i8_timestamps(const int64_t[:] stamps, tzinfo tz)
29 changes: 2 additions & 27 deletions pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ cpdef inline datetime localize_pydatetime(datetime dt, object tz):

@cython.wraparound(False)
@cython.boundscheck(False)
def normalize_i8_timestamps(int64_t[:] stamps, object tz):
cpdef ndarray[int64_t] normalize_i8_timestamps(const int64_t[:] stamps, tzinfo tz):
"""
Normalize each of the (nanosecond) timezone aware timestamps in the given
array by rounding down to the beginning of the day (i.e. midnight).
Expand All @@ -774,31 +774,6 @@ def normalize_i8_timestamps(int64_t[:] stamps, object tz):
stamps : int64 ndarray
tz : tzinfo or None

Returns
-------
result : int64 ndarray of converted of normalized nanosecond timestamps
"""
cdef:
int64_t[:] result

result = _normalize_local(stamps, tz)

return result.base # .base to access underlying np.ndarray


@cython.wraparound(False)
@cython.boundscheck(False)
cdef int64_t[:] _normalize_local(const int64_t[:] stamps, tzinfo tz):
"""
Normalize each of the (nanosecond) timestamps in the given array by
rounding down to the beginning of the day (i.e. midnight) for the
given timezone `tz`.

Parameters
----------
stamps : int64 ndarray
tz : tzinfo

Returns
-------
result : int64 ndarray of converted of normalized nanosecond timestamps
Expand Down Expand Up @@ -843,7 +818,7 @@ cdef int64_t[:] _normalize_local(const int64_t[:] stamps, tzinfo tz):
dt64_to_dtstruct(stamps[i] + deltas[pos[i]], &dts)
result[i] = _normalized_stamp(&dts)

return result
return result.base # `.base` to access underlying ndarray


cdef inline int64_t _normalized_stamp(npy_datetimestruct *dts) nogil:
Expand Down
34 changes: 24 additions & 10 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@ cnp.import_array()
from cpython.object cimport (PyObject_RichCompareBool, PyObject_RichCompare,
Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE)

from cpython.datetime cimport (datetime, time, PyDateTime_Check, PyDelta_Check,
PyTZInfo_Check, PyDateTime_IMPORT)
from cpython.datetime cimport (
datetime,
time,
tzinfo,
PyDateTime_Check,
PyDelta_Check,
PyTZInfo_Check,
PyDateTime_IMPORT,
)
PyDateTime_IMPORT

from pandas._libs.tslibs.util cimport (
Expand All @@ -29,10 +36,12 @@ from pandas._libs.tslibs.base cimport ABCTimedelta, ABCTimestamp

from pandas._libs.tslibs cimport ccalendar

from pandas._libs.tslibs.conversion import normalize_i8_timestamps
from pandas._libs.tslibs.conversion cimport (
_TSObject, convert_to_tsobject,
convert_datetime_to_tsobject)
_TSObject,
convert_to_tsobject,
convert_datetime_to_tsobject,
normalize_i8_timestamps,
)
from pandas._libs.tslibs.fields import get_start_end_field, get_date_name_field
from pandas._libs.tslibs.nattype cimport NPY_NAT, c_NaT as NaT
from pandas._libs.tslibs.np_datetime cimport (
Expand Down Expand Up @@ -1461,13 +1470,18 @@ default 'raise'
"""
Normalize Timestamp to midnight, preserving tz information.
"""
if self.tz is None or is_utc(self.tz):
cdef:
ndarray[int64_t] normalized
tzinfo own_tz = self.tzinfo # could be None

if own_tz is None or is_utc(own_tz):
DAY_NS = ccalendar.DAY_NANOS
normalized_value = self.value - (self.value % DAY_NS)
return Timestamp(normalized_value).tz_localize(self.tz)
normalized_value = normalize_i8_timestamps(
np.array([self.value], dtype='i8'), tz=self.tz)[0]
return Timestamp(normalized_value).tz_localize(self.tz)
return Timestamp(normalized_value).tz_localize(own_tz)

normalized = normalize_i8_timestamps(
np.array([self.value], dtype='i8'), tz=own_tz)
return Timestamp(normalized[0]).tz_localize(own_tz)


# Add the min and max fields at the class level
Expand Down