123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382 |
- """
- _Timestamp is a c-defined subclass of datetime.datetime
- _Timestamp is PITA. Because we inherit from datetime, which has very specific
- construction requirements, we need to do object instantiation in python
- (see Timestamp class below). This will serve as a C extension type that
- shadows the python class, where we do any heavy lifting.
- """
- import warnings
- cimport cython
- import numpy as np
- cimport numpy as cnp
- from numpy cimport (
- int64_t,
- ndarray,
- uint8_t,
- )
- cnp.import_array()
- from cpython.datetime cimport ( # alias bc `tzinfo` is a kwarg below
- PyDate_Check,
- PyDateTime_Check,
- PyDelta_Check,
- PyTZInfo_Check,
- datetime,
- import_datetime,
- time as dt_time,
- tzinfo as tzinfo_type,
- )
- from cpython.object cimport (
- Py_EQ,
- Py_GE,
- Py_GT,
- Py_LE,
- Py_LT,
- Py_NE,
- PyObject_RichCompare,
- PyObject_RichCompareBool,
- )
- import_datetime()
- from pandas._libs.tslibs cimport ccalendar
- from pandas._libs.tslibs.base cimport ABCTimestamp
- from pandas.util._exceptions import find_stack_level
- from pandas._libs.tslibs.conversion cimport (
- _TSObject,
- convert_datetime_to_tsobject,
- convert_to_tsobject,
- maybe_localize_tso,
- )
- from pandas._libs.tslibs.dtypes cimport (
- npy_unit_to_abbrev,
- periods_per_day,
- periods_per_second,
- )
- from pandas._libs.tslibs.util cimport (
- is_array,
- is_datetime64_object,
- is_integer_object,
- )
- from pandas._libs.tslibs.fields import (
- RoundTo,
- get_date_name_field,
- get_start_end_field,
- round_nsint64,
- )
- from pandas._libs.tslibs.nattype cimport (
- NPY_NAT,
- c_NaT as NaT,
- )
- from pandas._libs.tslibs.np_datetime cimport (
- NPY_DATETIMEUNIT,
- NPY_FR_ns,
- check_dts_bounds,
- cmp_dtstructs,
- cmp_scalar,
- convert_reso,
- get_datetime64_unit,
- get_datetime64_value,
- get_unit_from_dtype,
- npy_datetimestruct,
- npy_datetimestruct_to_datetime,
- pandas_datetime_to_datetimestruct,
- pydatetime_to_dtstruct,
- )
- from pandas._libs.tslibs.np_datetime import (
- OutOfBoundsDatetime,
- OutOfBoundsTimedelta,
- )
- from pandas._libs.tslibs.offsets cimport to_offset
- from pandas._libs.tslibs.timedeltas cimport (
- _Timedelta,
- delta_to_nanoseconds,
- is_any_td_scalar,
- )
- from pandas._libs.tslibs.timedeltas import Timedelta
- from pandas._libs.tslibs.timezones cimport (
- get_timezone,
- is_utc,
- maybe_get_tz,
- treat_tz_as_pytz,
- utc_stdlib as UTC,
- )
- from pandas._libs.tslibs.tzconversion cimport (
- tz_convert_from_utc_single,
- tz_localize_to_utc_single,
- )
- # ----------------------------------------------------------------------
- # Constants
- _zero_time = dt_time(0, 0)
- _no_input = object()
- # ----------------------------------------------------------------------
- cdef _Timestamp create_timestamp_from_ts(
- int64_t value,
- npy_datetimestruct dts,
- tzinfo tz,
- bint fold,
- NPY_DATETIMEUNIT reso=NPY_FR_ns,
- ):
- """ convenience routine to construct a Timestamp from its parts """
- cdef:
- _Timestamp ts_base
- int64_t pass_year = dts.year
- # We pass year=1970/1972 here and set year below because with non-nanosecond
- # resolution we may have datetimes outside of the stdlib pydatetime
- # implementation bounds, which would raise.
- # NB: this means the C-API macro PyDateTime_GET_YEAR is unreliable.
- if 1 <= pass_year <= 9999:
- # we are in-bounds for pydatetime
- pass
- elif ccalendar.is_leapyear(dts.year):
- pass_year = 1972
- else:
- pass_year = 1970
- ts_base = _Timestamp.__new__(Timestamp, pass_year, dts.month,
- dts.day, dts.hour, dts.min,
- dts.sec, dts.us, tz, fold=fold)
- ts_base._value = value
- ts_base.year = dts.year
- ts_base.nanosecond = dts.ps // 1000
- ts_base._creso = reso
- return ts_base
- def _unpickle_timestamp(value, freq, tz, reso=NPY_FR_ns):
- # GH#41949 dont warn on unpickle if we have a freq
- ts = Timestamp._from_value_and_reso(value, reso, tz)
- return ts
- # ----------------------------------------------------------------------
- def integer_op_not_supported(obj):
- # GH#22535 add/sub of integers and int-arrays is no longer allowed
- # Note we return rather than raise the exception so we can raise in
- # the caller; mypy finds this more palatable.
- cls = type(obj).__name__
- # GH#30886 using an fstring raises SystemError
- int_addsub_msg = (
- f"Addition/subtraction of integers and integer-arrays with {cls} is "
- "no longer supported. Instead of adding/subtracting `n`, "
- "use `n * obj.freq`"
- )
- return TypeError(int_addsub_msg)
- class MinMaxReso:
- """
- We need to define min/max/resolution on both the Timestamp _instance_
- and Timestamp class. On an instance, these depend on the object's _reso.
- On the class, we default to the values we would get with nanosecond _reso.
- See also: timedeltas.MinMaxReso
- """
- def __init__(self, name):
- self._name = name
- def __get__(self, obj, type=None):
- cls = Timestamp
- if self._name == "min":
- val = np.iinfo(np.int64).min + 1
- elif self._name == "max":
- val = np.iinfo(np.int64).max
- else:
- assert self._name == "resolution"
- val = 1
- cls = Timedelta
- if obj is None:
- # i.e. this is on the class, default to nanos
- return cls(val)
- elif self._name == "resolution":
- return Timedelta._from_value_and_reso(val, obj._creso)
- else:
- return Timestamp._from_value_and_reso(val, obj._creso, tz=None)
- def __set__(self, obj, value):
- raise AttributeError(f"{self._name} is not settable.")
- # ----------------------------------------------------------------------
- cdef class _Timestamp(ABCTimestamp):
- # higher than np.ndarray and np.matrix
- __array_priority__ = 100
- dayofweek = _Timestamp.day_of_week
- dayofyear = _Timestamp.day_of_year
- min = MinMaxReso("min")
- max = MinMaxReso("max")
- resolution = MinMaxReso("resolution") # GH#21336, GH#21365
- @property
- def value(self) -> int:
- try:
- return convert_reso(self._value, self._creso, NPY_FR_ns, False)
- except OverflowError:
- raise OverflowError(
- "Cannot convert Timestamp to nanoseconds without overflow. "
- "Use `.asm8.view('i8')` to cast represent Timestamp in its own "
- f"unit (here, {self.unit})."
- )
- @property
- def unit(self) -> str:
- """
- The abbreviation associated with self._creso.
- Examples
- --------
- >>> pd.Timestamp("2020-01-01 12:34:56").unit
- 's'
- >>> pd.Timestamp("2020-01-01 12:34:56.123").unit
- 'ms'
- >>> pd.Timestamp("2020-01-01 12:34:56.123456").unit
- 'us'
- >>> pd.Timestamp("2020-01-01 12:34:56.123456789").unit
- 'ns'
- """
- return npy_unit_to_abbrev(self._creso)
- # -----------------------------------------------------------------
- # Constructors
- @classmethod
- def _from_value_and_reso(cls, int64_t value, NPY_DATETIMEUNIT reso, tzinfo tz):
- cdef:
- _TSObject obj = _TSObject()
- if value == NPY_NAT:
- return NaT
- if reso < NPY_DATETIMEUNIT.NPY_FR_s or reso > NPY_DATETIMEUNIT.NPY_FR_ns:
- raise NotImplementedError(
- "Only resolutions 's', 'ms', 'us', 'ns' are supported."
- )
- obj.value = value
- obj.creso = reso
- pandas_datetime_to_datetimestruct(value, reso, &obj.dts)
- maybe_localize_tso(obj, tz, reso)
- return create_timestamp_from_ts(
- value, obj.dts, tz=obj.tzinfo, fold=obj.fold, reso=reso
- )
- @classmethod
- def _from_dt64(cls, dt64: np.datetime64):
- # construct a Timestamp from a np.datetime64 object, keeping the
- # resolution of the input.
- # This is herely mainly so we can incrementally implement non-nano
- # (e.g. only tznaive at first)
- cdef:
- int64_t value
- NPY_DATETIMEUNIT reso
- reso = get_datetime64_unit(dt64)
- value = get_datetime64_value(dt64)
- return cls._from_value_and_reso(value, reso, None)
- # -----------------------------------------------------------------
- def __hash__(_Timestamp self):
- if self.nanosecond:
- return hash(self._value)
- if not (1 <= self.year <= 9999):
- # out of bounds for pydatetime
- return hash(self._value)
- if self.fold:
- return datetime.__hash__(self.replace(fold=0))
- return datetime.__hash__(self)
- def __richcmp__(_Timestamp self, object other, int op):
- cdef:
- _Timestamp ots
- if isinstance(other, _Timestamp):
- ots = other
- elif other is NaT:
- return op == Py_NE
- elif is_datetime64_object(other):
- ots = Timestamp(other)
- elif PyDateTime_Check(other):
- if self.nanosecond == 0:
- val = self.to_pydatetime()
- return PyObject_RichCompareBool(val, other, op)
- try:
- ots = type(self)(other)
- except ValueError:
- return self._compare_outside_nanorange(other, op)
- elif is_array(other):
- # avoid recursion error GH#15183
- if other.dtype.kind == "M":
- if self.tz is None:
- return PyObject_RichCompare(self.asm8, other, op)
- elif op == Py_NE:
- return np.ones(other.shape, dtype=np.bool_)
- elif op == Py_EQ:
- return np.zeros(other.shape, dtype=np.bool_)
- raise TypeError(
- "Cannot compare tz-naive and tz-aware timestamps"
- )
- elif other.dtype.kind == "O":
- # Operate element-wise
- return np.array(
- [PyObject_RichCompare(self, x, op) for x in other],
- dtype=bool,
- )
- elif op == Py_NE:
- return np.ones(other.shape, dtype=np.bool_)
- elif op == Py_EQ:
- return np.zeros(other.shape, dtype=np.bool_)
- return NotImplemented
- elif PyDate_Check(other):
- # returning NotImplemented defers to the `date` implementation
- # which incorrectly drops tz and normalizes to midnight
- # before comparing
- # We follow the stdlib datetime behavior of never being equal
- if op == Py_EQ:
- return False
- elif op == Py_NE:
- return True
- raise TypeError(
- "Cannot compare Timestamp with datetime.date. "
- "Use ts == pd.Timestamp(date) or ts.date() == date instead."
- )
- else:
- return NotImplemented
- if not self._can_compare(ots):
- if op == Py_NE or op == Py_EQ:
- return NotImplemented
- raise TypeError(
- "Cannot compare tz-naive and tz-aware timestamps"
- )
- if self._creso == ots._creso:
- return cmp_scalar(self._value, ots._value, op)
- return self._compare_mismatched_resos(ots, op)
- # TODO: copied from Timedelta; try to de-duplicate
- cdef bint _compare_mismatched_resos(self, _Timestamp other, int op):
- # Can't just dispatch to numpy as they silently overflow and get it wrong
- cdef:
- npy_datetimestruct dts_self
- npy_datetimestruct dts_other
- # dispatch to the datetimestruct utils instead of writing new ones!
- pandas_datetime_to_datetimestruct(self._value, self._creso, &dts_self)
- pandas_datetime_to_datetimestruct(other._value, other._creso, &dts_other)
- return cmp_dtstructs(&dts_self, &dts_other, op)
- cdef bint _compare_outside_nanorange(_Timestamp self, datetime other,
- int op) except -1:
- cdef:
- datetime dtval = self.to_pydatetime(warn=False)
- if not self._can_compare(other):
- return NotImplemented
- if self.nanosecond == 0:
- return PyObject_RichCompareBool(dtval, other, op)
- # otherwise we have dtval < self
- if op == Py_NE:
- return True
- if op == Py_EQ:
- return False
- if op == Py_LE or op == Py_LT:
- return self.year <= other.year
- if op == Py_GE or op == Py_GT:
- return self.year >= other.year
- cdef bint _can_compare(self, datetime other):
- if self.tzinfo is not None:
- return other.tzinfo is not None
- return other.tzinfo is None
- @cython.overflowcheck(True)
- def __add__(self, other):
- cdef:
- int64_t nanos = 0
- if is_any_td_scalar(other):
- other = Timedelta(other)
- # TODO: share this with __sub__, Timedelta.__add__
- # Matching numpy, we cast to the higher resolution. Unlike numpy,
- # we raise instead of silently overflowing during this casting.
- if self._creso < other._creso:
- self = (<_Timestamp>self)._as_creso(other._creso, round_ok=True)
- elif self._creso > other._creso:
- other = (<_Timedelta>other)._as_creso(self._creso, round_ok=True)
- nanos = other._value
- try:
- new_value = self._value+ nanos
- result = type(self)._from_value_and_reso(
- new_value, reso=self._creso, tz=self.tzinfo
- )
- except OverflowError as err:
- # TODO: don't hard-code nanosecond here
- new_value = int(self._value) + int(nanos)
- raise OutOfBoundsDatetime(
- f"Out of bounds nanosecond timestamp: {new_value}"
- ) from err
- return result
- elif is_integer_object(other):
- raise integer_op_not_supported(self)
- elif is_array(other):
- if other.dtype.kind in ["i", "u"]:
- raise integer_op_not_supported(self)
- if other.dtype.kind == "m":
- if self.tz is None:
- return self.asm8 + other
- return np.asarray(
- [self + other[n] for n in range(len(other))],
- dtype=object,
- )
- elif not isinstance(self, _Timestamp):
- # cython semantics, args have been switched and this is __radd__
- # TODO(cython3): remove this it moved to __radd__
- return other.__add__(self)
- return NotImplemented
- def __radd__(self, other):
- # Have to duplicate checks to avoid infinite recursion due to NotImplemented
- if is_any_td_scalar(other) or is_integer_object(other) or is_array(other):
- return self.__add__(other)
- return NotImplemented
- def __sub__(self, other):
- if other is NaT:
- return NaT
- elif is_any_td_scalar(other) or is_integer_object(other):
- neg_other = -other
- return self + neg_other
- elif is_array(other):
- if other.dtype.kind in ["i", "u"]:
- raise integer_op_not_supported(self)
- if other.dtype.kind == "m":
- if self.tz is None:
- return self.asm8 - other
- return np.asarray(
- [self - other[n] for n in range(len(other))],
- dtype=object,
- )
- return NotImplemented
- # coerce if necessary if we are a Timestamp-like
- if (PyDateTime_Check(self)
- and (PyDateTime_Check(other) or is_datetime64_object(other))):
- # both_timestamps is to determine whether Timedelta(self - other)
- # should raise the OOB error, or fall back returning a timedelta.
- # TODO(cython3): clean out the bits that moved to __rsub__
- both_timestamps = (isinstance(other, _Timestamp) and
- isinstance(self, _Timestamp))
- if isinstance(self, _Timestamp):
- other = type(self)(other)
- else:
- self = type(other)(self)
- if (self.tzinfo is None) ^ (other.tzinfo is None):
- raise TypeError(
- "Cannot subtract tz-naive and tz-aware datetime-like objects."
- )
- # Matching numpy, we cast to the higher resolution. Unlike numpy,
- # we raise instead of silently overflowing during this casting.
- if self._creso < other._creso:
- self = (<_Timestamp>self)._as_creso(other._creso, round_ok=True)
- elif self._creso > other._creso:
- other = (<_Timestamp>other)._as_creso(self._creso, round_ok=True)
- # scalar Timestamp/datetime - Timestamp/datetime -> yields a
- # Timedelta
- try:
- res_value = self._value- other._value
- return Timedelta._from_value_and_reso(res_value, self._creso)
- except (OverflowError, OutOfBoundsDatetime, OutOfBoundsTimedelta) as err:
- if isinstance(other, _Timestamp):
- if both_timestamps:
- raise OutOfBoundsDatetime(
- "Result is too large for pandas.Timedelta. Convert inputs "
- "to datetime.datetime with 'Timestamp.to_pydatetime()' "
- "before subtracting."
- ) from err
- # We get here in stata tests, fall back to stdlib datetime
- # method and return stdlib timedelta object
- pass
- elif is_datetime64_object(self):
- # GH#28286 cython semantics for __rsub__, `other` is actually
- # the Timestamp
- # TODO(cython3): remove this, this moved to __rsub__
- return type(other)(self) - other
- return NotImplemented
- def __rsub__(self, other):
- if PyDateTime_Check(other):
- try:
- return type(self)(other) - self
- except (OverflowError, OutOfBoundsDatetime) as err:
- # We get here in stata tests, fall back to stdlib datetime
- # method and return stdlib timedelta object
- pass
- elif is_datetime64_object(other):
- return type(self)(other) - self
- return NotImplemented
- # -----------------------------------------------------------------
- cdef int64_t _maybe_convert_value_to_local(self):
- """Convert UTC i8 value to local i8 value if tz exists"""
- cdef:
- int64_t val
- tzinfo own_tz = self.tzinfo
- npy_datetimestruct dts
- if own_tz is not None and not is_utc(own_tz):
- pydatetime_to_dtstruct(self, &dts)
- val = npy_datetimestruct_to_datetime(self._creso, &dts) + self.nanosecond
- else:
- val = self._value
- return val
- @cython.boundscheck(False)
- cdef bint _get_start_end_field(self, str field, freq):
- cdef:
- int64_t val
- dict kwds
- ndarray[uint8_t, cast=True] out
- int month_kw
- if freq:
- kwds = freq.kwds
- month_kw = kwds.get("startingMonth", kwds.get("month", 12))
- freqstr = freq.freqstr
- else:
- month_kw = 12
- freqstr = None
- val = self._maybe_convert_value_to_local()
- out = get_start_end_field(np.array([val], dtype=np.int64),
- field, freqstr, month_kw, self._creso)
- return out[0]
- @property
- def is_month_start(self) -> bool:
- """
- Check if the date is the first day of the month.
- Returns
- -------
- bool
- True if the date is the first day of the month.
- See Also
- --------
- Timestamp.is_month_end : Similar property indicating the last day of the month.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_month_start
- False
- >>> ts = pd.Timestamp(2020, 1, 1)
- >>> ts.is_month_start
- True
- """
- return self.day == 1
- @property
- def is_month_end(self) -> bool:
- """
- Check if the date is the last day of the month.
- Returns
- -------
- bool
- True if the date is the last day of the month.
- See Also
- --------
- Timestamp.is_month_start : Similar property indicating month start.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_month_end
- False
- >>> ts = pd.Timestamp(2020, 12, 31)
- >>> ts.is_month_end
- True
- """
- return self.day == self.days_in_month
- @property
- def is_quarter_start(self) -> bool:
- """
- Check if the date is the first day of the quarter.
- Returns
- -------
- bool
- True if date is first day of the quarter.
- See Also
- --------
- Timestamp.is_quarter_end : Similar property indicating the quarter end.
- Timestamp.quarter : Return the quarter of the date.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_quarter_start
- False
- >>> ts = pd.Timestamp(2020, 4, 1)
- >>> ts.is_quarter_start
- True
- """
- return self.day == 1 and self.month % 3 == 1
- @property
- def is_quarter_end(self) -> bool:
- """
- Check if date is last day of the quarter.
- Returns
- -------
- bool
- True if date is last day of the quarter.
- See Also
- --------
- Timestamp.is_quarter_start : Similar property indicating the quarter start.
- Timestamp.quarter : Return the quarter of the date.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_quarter_end
- False
- >>> ts = pd.Timestamp(2020, 3, 31)
- >>> ts.is_quarter_end
- True
- """
- return (self.month % 3) == 0 and self.day == self.days_in_month
- @property
- def is_year_start(self) -> bool:
- """
- Return True if date is first day of the year.
- Returns
- -------
- bool
- See Also
- --------
- Timestamp.is_year_end : Similar property indicating the end of the year.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_year_start
- False
- >>> ts = pd.Timestamp(2020, 1, 1)
- >>> ts.is_year_start
- True
- """
- return self.day == self.month == 1
- @property
- def is_year_end(self) -> bool:
- """
- Return True if date is last day of the year.
- Returns
- -------
- bool
- See Also
- --------
- Timestamp.is_year_start : Similar property indicating the start of the year.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_year_end
- False
- >>> ts = pd.Timestamp(2020, 12, 31)
- >>> ts.is_year_end
- True
- """
- return self.month == 12 and self.day == 31
- @cython.boundscheck(False)
- cdef _get_date_name_field(self, str field, object locale):
- cdef:
- int64_t val
- object[::1] out
- val = self._maybe_convert_value_to_local()
- out = get_date_name_field(np.array([val], dtype=np.int64),
- field, locale=locale, reso=self._creso)
- return out[0]
- def day_name(self, locale=None) -> str:
- """
- Return the day name of the Timestamp with specified locale.
- Parameters
- ----------
- locale : str, default None (English locale)
- Locale determining the language in which to return the day name.
- Returns
- -------
- str
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts.day_name()
- 'Saturday'
- Analogous for ``pd.NaT``:
- >>> pd.NaT.day_name()
- nan
- """
- return self._get_date_name_field("day_name", locale)
- def month_name(self, locale=None) -> str:
- """
- Return the month name of the Timestamp with specified locale.
- Parameters
- ----------
- locale : str, default None (English locale)
- Locale determining the language in which to return the month name.
- Returns
- -------
- str
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts.month_name()
- 'March'
- Analogous for ``pd.NaT``:
- >>> pd.NaT.month_name()
- nan
- """
- return self._get_date_name_field("month_name", locale)
- @property
- def is_leap_year(self) -> bool:
- """
- Return True if year is a leap year.
- Returns
- -------
- bool
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.is_leap_year
- True
- """
- return bool(ccalendar.is_leapyear(self.year))
- @property
- def day_of_week(self) -> int:
- """
- Return day of the week.
- Returns
- -------
- int
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.day_of_week
- 5
- """
- return self.weekday()
- @property
- def day_of_year(self) -> int:
- """
- Return the day of the year.
- Returns
- -------
- int
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.day_of_year
- 74
- """
- return ccalendar.get_day_of_year(self.year, self.month, self.day)
- @property
- def quarter(self) -> int:
- """
- Return the quarter of the year.
- Returns
- -------
- int
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.quarter
- 1
- """
- return ((self.month - 1) // 3) + 1
- @property
- def week(self) -> int:
- """
- Return the week number of the year.
- Returns
- -------
- int
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.week
- 11
- """
- return ccalendar.get_week_of_year(self.year, self.month, self.day)
- @property
- def days_in_month(self) -> int:
- """
- Return the number of days in the month.
- Returns
- -------
- int
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14)
- >>> ts.days_in_month
- 31
- """
- return ccalendar.get_days_in_month(self.year, self.month)
- # -----------------------------------------------------------------
- # Transformation Methods
- def normalize(self) -> "Timestamp":
- """
- Normalize Timestamp to midnight, preserving tz information.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14, 15, 30)
- >>> ts.normalize()
- Timestamp('2020-03-14 00:00:00')
- """
- cdef:
- local_val = self._maybe_convert_value_to_local()
- int64_t normalized
- int64_t ppd = periods_per_day(self._creso)
- _Timestamp ts
- normalized = normalize_i8_stamp(local_val, ppd)
- ts = type(self)._from_value_and_reso(normalized, reso=self._creso, tz=None)
- return ts.tz_localize(self.tzinfo)
- # -----------------------------------------------------------------
- # Pickle Methods
- def __reduce_ex__(self, protocol):
- # python 3.6 compat
- # https://bugs.python.org/issue28730
- # now __reduce_ex__ is defined and higher priority than __reduce__
- return self.__reduce__()
- def __setstate__(self, state):
- self._value= state[0]
- self.tzinfo = state[2]
- if len(state) == 3:
- # pre-non-nano pickle
- # TODO: no tests get here 2022-05-10
- reso = NPY_FR_ns
- else:
- reso = state[4]
- self._creso = reso
- def __reduce__(self):
- object_state = self._value, None, self.tzinfo, self._creso
- return (_unpickle_timestamp, object_state)
- # -----------------------------------------------------------------
- # Rendering Methods
- def isoformat(self, sep: str = "T", timespec: str = "auto") -> str:
- """
- Return the time formatted according to ISO 8610.
- The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmmnnn'.
- By default, the fractional part is omitted if self.microsecond == 0
- and self.nanosecond == 0.
- If self.tzinfo is not None, the UTC offset is also attached, giving
- giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmmnnn+HH:MM'.
- Parameters
- ----------
- sep : str, default 'T'
- String used as the separator between the date and time.
- timespec : str, default 'auto'
- Specifies the number of additional terms of the time to include.
- The valid values are 'auto', 'hours', 'minutes', 'seconds',
- 'milliseconds', 'microseconds', and 'nanoseconds'.
- Returns
- -------
- str
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts.isoformat()
- '2020-03-14T15:32:52.192548651'
- >>> ts.isoformat(timespec='microseconds')
- '2020-03-14T15:32:52.192548'
- """
- base_ts = "microseconds" if timespec == "nanoseconds" else timespec
- base = super(_Timestamp, self).isoformat(sep=sep, timespec=base_ts)
- # We need to replace the fake year 1970 with our real year
- base = f"{self.year:04d}-" + base.split("-", 1)[1]
- if self.nanosecond == 0 and timespec != "nanoseconds":
- return base
- if self.tzinfo is not None:
- base1, base2 = base[:-6], base[-6:]
- else:
- base1, base2 = base, ""
- if timespec == "nanoseconds" or (timespec == "auto" and self.nanosecond):
- if self.microsecond:
- base1 += f"{self.nanosecond:03d}"
- else:
- base1 += f".{self.nanosecond:09d}"
- return base1 + base2
- def __repr__(self) -> str:
- stamp = self._repr_base
- zone = None
- if self.tzinfo is not None:
- try:
- stamp += self.strftime("%z")
- except ValueError:
- year2000 = self.replace(year=2000)
- stamp += year2000.strftime("%z")
- zone = get_timezone(self.tzinfo)
- try:
- stamp += zone.strftime(" %%Z")
- except AttributeError:
- # e.g. tzlocal has no `strftime`
- pass
- tz = f", tz='{zone}'" if zone is not None else ""
- return f"Timestamp('{stamp}'{tz})"
- @property
- def _repr_base(self) -> str:
- return f"{self._date_repr} {self._time_repr}"
- @property
- def _date_repr(self) -> str:
- # Ideal here would be self.strftime("%Y-%m-%d"), but
- # the datetime strftime() methods require year >= 1900 and is slower
- return f"{self.year}-{self.month:02d}-{self.day:02d}"
- @property
- def _time_repr(self) -> str:
- result = f"{self.hour:02d}:{self.minute:02d}:{self.second:02d}"
- if self.nanosecond != 0:
- result += f".{self.nanosecond + 1000 * self.microsecond:09d}"
- elif self.microsecond != 0:
- result += f".{self.microsecond:06d}"
- return result
- @property
- def _short_repr(self) -> str:
- # format a Timestamp with only _date_repr if possible
- # otherwise _repr_base
- if (self.hour == 0 and
- self.minute == 0 and
- self.second == 0 and
- self.microsecond == 0 and
- self.nanosecond == 0):
- return self._date_repr
- return self._repr_base
- # -----------------------------------------------------------------
- # Conversion Methods
- @cython.cdivision(False)
- cdef _Timestamp _as_creso(self, NPY_DATETIMEUNIT creso, bint round_ok=True):
- cdef:
- int64_t value
- if creso == self._creso:
- return self
- try:
- value = convert_reso(self._value, self._creso, creso, round_ok=round_ok)
- except OverflowError as err:
- unit = npy_unit_to_abbrev(creso)
- raise OutOfBoundsDatetime(
- f"Cannot cast {self} to unit='{unit}' without overflow."
- ) from err
- return type(self)._from_value_and_reso(value, reso=creso, tz=self.tzinfo)
- def as_unit(self, str unit, bint round_ok=True):
- """
- Convert the underlying int64 representaton to the given unit.
- Parameters
- ----------
- unit : {"ns", "us", "ms", "s"}
- round_ok : bool, default True
- If False and the conversion requires rounding, raise.
- Returns
- -------
- Timestamp
- """
- dtype = np.dtype(f"M8[{unit}]")
- reso = get_unit_from_dtype(dtype)
- try:
- return self._as_creso(reso, round_ok=round_ok)
- except OverflowError as err:
- raise OutOfBoundsDatetime(
- f"Cannot cast {self} to unit='{unit}' without overflow."
- ) from err
- @property
- def asm8(self) -> np.datetime64:
- """
- Return numpy datetime64 format in nanoseconds.
- Examples
- --------
- >>> ts = pd.Timestamp(2020, 3, 14, 15)
- >>> ts.asm8
- numpy.datetime64('2020-03-14T15:00:00.000000')
- """
- return self.to_datetime64()
- def timestamp(self):
- """
- Return POSIX timestamp as float.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548')
- >>> ts.timestamp()
- 1584199972.192548
- """
- # GH 17329
- # Note: Naive timestamps will not match datetime.stdlib
- denom = periods_per_second(self._creso)
- return round(self._value/ denom, 6)
- cpdef datetime to_pydatetime(_Timestamp self, bint warn=True):
- """
- Convert a Timestamp object to a native Python datetime object.
- If warn=True, issue a warning if nanoseconds is nonzero.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548')
- >>> ts.to_pydatetime()
- datetime.datetime(2020, 3, 14, 15, 32, 52, 192548)
- Analogous for ``pd.NaT``:
- >>> pd.NaT.to_pydatetime()
- NaT
- """
- if self.nanosecond != 0 and warn:
- warnings.warn("Discarding nonzero nanoseconds in conversion.",
- UserWarning, stacklevel=find_stack_level())
- return datetime(self.year, self.month, self.day,
- self.hour, self.minute, self.second,
- self.microsecond, self.tzinfo, fold=self.fold)
- cpdef to_datetime64(self):
- """
- Return a numpy.datetime64 object with 'ns' precision.
- """
- # TODO: find a way to construct dt64 directly from _reso
- abbrev = npy_unit_to_abbrev(self._creso)
- return np.datetime64(self._value, abbrev)
- def to_numpy(self, dtype=None, copy=False) -> np.datetime64:
- """
- Convert the Timestamp to a NumPy datetime64.
- This is an alias method for `Timestamp.to_datetime64()`. The dtype and
- copy parameters are available here only for compatibility. Their values
- will not affect the return value.
- Returns
- -------
- numpy.datetime64
- See Also
- --------
- DatetimeIndex.to_numpy : Similar method for DatetimeIndex.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts.to_numpy()
- numpy.datetime64('2020-03-14T15:32:52.192548651')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.to_numpy()
- numpy.datetime64('NaT')
- """
- if dtype is not None or copy is not False:
- raise ValueError(
- "Timestamp.to_numpy dtype and copy arguments are ignored."
- )
- return self.to_datetime64()
- def to_period(self, freq=None):
- """
- Return an period of which this timestamp is an observation.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> # Year end frequency
- >>> ts.to_period(freq='Y')
- Period('2020', 'A-DEC')
- >>> # Month end frequency
- >>> ts.to_period(freq='M')
- Period('2020-03', 'M')
- >>> # Weekly frequency
- >>> ts.to_period(freq='W')
- Period('2020-03-09/2020-03-15', 'W-SUN')
- >>> # Quarter end frequency
- >>> ts.to_period(freq='Q')
- Period('2020Q1', 'Q-DEC')
- """
- from pandas import Period
- if self.tz is not None:
- # GH#21333
- warnings.warn(
- "Converting to Period representation will drop timezone information.",
- UserWarning,
- stacklevel=find_stack_level(),
- )
- return Period(self, freq=freq)
- # ----------------------------------------------------------------------
- # Python front end to C extension type _Timestamp
- # This serves as the box for datetime64
- class Timestamp(_Timestamp):
- """
- Pandas replacement for python datetime.datetime object.
- Timestamp is the pandas equivalent of python's Datetime
- and is interchangeable with it in most cases. It's the type used
- for the entries that make up a DatetimeIndex, and other timeseries
- oriented data structures in pandas.
- Parameters
- ----------
- ts_input : datetime-like, str, int, float
- Value to be converted to Timestamp.
- year, month, day : int
- hour, minute, second, microsecond : int, optional, default 0
- tzinfo : datetime.tzinfo, optional, default None
- nanosecond : int, optional, default 0
- tz : str, pytz.timezone, dateutil.tz.tzfile or None
- Time zone for time which Timestamp will have.
- unit : str
- Unit used for conversion if ts_input is of type int or float. The
- valid values are 'D', 'h', 'm', 's', 'ms', 'us', and 'ns'. For
- example, 's' means seconds and 'ms' means milliseconds.
- For float inputs, the result will be stored in nanoseconds, and
- the unit attribute will be set as ``'ns'``.
- fold : {0, 1}, default None, keyword-only
- Due to daylight saving time, one wall clock time can occur twice
- when shifting from summer to winter time; fold describes whether the
- datetime-like corresponds to the first (0) or the second time (1)
- the wall clock hits the ambiguous time.
- .. versionadded:: 1.1.0
- Notes
- -----
- There are essentially three calling conventions for the constructor. The
- primary form accepts four parameters. They can be passed by position or
- keyword.
- The other two forms mimic the parameters from ``datetime.datetime``. They
- can be passed by either position or keyword, but not both mixed together.
- Examples
- --------
- Using the primary calling convention:
- This converts a datetime-like string
- >>> pd.Timestamp('2017-01-01T12')
- Timestamp('2017-01-01 12:00:00')
- This converts a float representing a Unix epoch in units of seconds
- >>> pd.Timestamp(1513393355.5, unit='s')
- Timestamp('2017-12-16 03:02:35.500000')
- This converts an int representing a Unix-epoch in units of seconds
- and for a particular timezone
- >>> pd.Timestamp(1513393355, unit='s', tz='US/Pacific')
- Timestamp('2017-12-15 19:02:35-0800', tz='US/Pacific')
- Using the other two forms that mimic the API for ``datetime.datetime``:
- >>> pd.Timestamp(2017, 1, 1, 12)
- Timestamp('2017-01-01 12:00:00')
- >>> pd.Timestamp(year=2017, month=1, day=1, hour=12)
- Timestamp('2017-01-01 12:00:00')
- """
- @classmethod
- def fromordinal(cls, ordinal, tz=None):
- """
- Construct a timestamp from a a proleptic Gregorian ordinal.
- Parameters
- ----------
- ordinal : int
- Date corresponding to a proleptic Gregorian ordinal.
- tz : str, pytz.timezone, dateutil.tz.tzfile or None
- Time zone for the Timestamp.
- Notes
- -----
- By definition there cannot be any tz info on the ordinal itself.
- Examples
- --------
- >>> pd.Timestamp.fromordinal(737425)
- Timestamp('2020-01-01 00:00:00')
- """
- return cls(datetime.fromordinal(ordinal), tz=tz)
- @classmethod
- def now(cls, tz=None):
- """
- Return new Timestamp object representing current time local to tz.
- Parameters
- ----------
- tz : str or timezone object, default None
- Timezone to localize to.
- Examples
- --------
- >>> pd.Timestamp.now() # doctest: +SKIP
- Timestamp('2020-11-16 22:06:16.378782')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.now()
- NaT
- """
- if isinstance(tz, str):
- tz = maybe_get_tz(tz)
- return cls(datetime.now(tz))
- @classmethod
- def today(cls, tz=None):
- """
- Return the current time in the local timezone.
- This differs from datetime.today() in that it can be localized to a
- passed timezone.
- Parameters
- ----------
- tz : str or timezone object, default None
- Timezone to localize to.
- Examples
- --------
- >>> pd.Timestamp.today() # doctest: +SKIP
- Timestamp('2020-11-16 22:37:39.969883')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.today()
- NaT
- """
- return cls.now(tz)
- @classmethod
- def utcnow(cls):
- """
- Timestamp.utcnow()
- Return a new Timestamp representing UTC day and time.
- Examples
- --------
- >>> pd.Timestamp.utcnow() # doctest: +SKIP
- Timestamp('2020-11-16 22:50:18.092888+0000', tz='UTC')
- """
- return cls.now(UTC)
- @classmethod
- def utcfromtimestamp(cls, ts):
- """
- Timestamp.utcfromtimestamp(ts)
- Construct a timezone-aware UTC datetime from a POSIX timestamp.
- Notes
- -----
- Timestamp.utcfromtimestamp behavior differs from datetime.utcfromtimestamp
- in returning a timezone-aware object.
- Examples
- --------
- >>> pd.Timestamp.utcfromtimestamp(1584199972)
- Timestamp('2020-03-14 15:32:52+0000', tz='UTC')
- """
- # GH#22451
- return cls.fromtimestamp(ts, tz="UTC")
- @classmethod
- def fromtimestamp(cls, ts, tz=None):
- """
- Timestamp.fromtimestamp(ts)
- Transform timestamp[, tz] to tz's local time from POSIX timestamp.
- Examples
- --------
- >>> pd.Timestamp.fromtimestamp(1584199972) # doctest: +SKIP
- Timestamp('2020-03-14 15:32:52')
- Note that the output may change depending on your local time.
- """
- tz = maybe_get_tz(tz)
- return cls(datetime.fromtimestamp(ts, tz))
- def strftime(self, format):
- """
- Return a formatted string of the Timestamp.
- Parameters
- ----------
- format : str
- Format string to convert Timestamp to string.
- See strftime documentation for more information on the format string:
- https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts.strftime('%Y-%m-%d %X')
- '2020-03-14 15:32:52'
- """
- try:
- _dt = datetime(self.year, self.month, self.day,
- self.hour, self.minute, self.second,
- self.microsecond, self.tzinfo, fold=self.fold)
- except ValueError as err:
- raise NotImplementedError(
- "strftime not yet supported on Timestamps which "
- "are outside the range of Python's standard library. "
- "For now, please call the components you need (such as `.year` "
- "and `.month`) and construct your string from there."
- ) from err
- return _dt.strftime(format)
- # Issue 25016.
- @classmethod
- def strptime(cls, date_string, format):
- """
- Timestamp.strptime(string, format)
- Function is not implemented. Use pd.to_datetime().
- """
- raise NotImplementedError(
- "Timestamp.strptime() is not implemented. "
- "Use to_datetime() to parse date strings."
- )
- @classmethod
- def combine(cls, date, time):
- """
- Timestamp.combine(date, time)
- Combine date, time into datetime with same date and time fields.
- Examples
- --------
- >>> from datetime import date, time
- >>> pd.Timestamp.combine(date(2020, 3, 14), time(15, 30, 15))
- Timestamp('2020-03-14 15:30:15')
- """
- return cls(datetime.combine(date, time))
- def __new__(
- cls,
- object ts_input=_no_input,
- year=None,
- month=None,
- day=None,
- hour=None,
- minute=None,
- second=None,
- microsecond=None,
- tzinfo_type tzinfo=None,
- *,
- nanosecond=None,
- tz=None,
- unit=None,
- fold=None,
- ):
- # The parameter list folds together legacy parameter names (the first
- # four) and positional and keyword parameter names from pydatetime.
- #
- # There are three calling forms:
- #
- # - In the legacy form, the first parameter, ts_input, is required
- # and may be datetime-like, str, int, or float. The second
- # parameter, offset, is optional and may be str or DateOffset.
- #
- # - ints in the first, second, and third arguments indicate
- # pydatetime positional arguments. Only the first 8 arguments
- # (standing in for year, month, day, hour, minute, second,
- # microsecond, tzinfo) may be non-None. As a shortcut, we just
- # check that the second argument is an int.
- #
- # - Nones for the first four (legacy) arguments indicate pydatetime
- # keyword arguments. year, month, and day are required. As a
- # shortcut, we just check that the first argument was not passed.
- #
- # Mixing pydatetime positional and keyword arguments is forbidden!
- cdef:
- _TSObject ts
- tzinfo_type tzobj
- _date_attributes = [year, month, day, hour, minute, second,
- microsecond, nanosecond]
- if tzinfo is not None:
- # GH#17690 tzinfo must be a datetime.tzinfo object, ensured
- # by the cython annotation.
- if tz is not None:
- raise ValueError("Can provide at most one of tz, tzinfo")
- # User passed tzinfo instead of tz; avoid silently ignoring
- tz, tzinfo = tzinfo, None
- # Allow fold only for unambiguous input
- if fold is not None:
- if fold not in [0, 1]:
- raise ValueError(
- "Valid values for the fold argument are None, 0, or 1."
- )
- if (ts_input is not _no_input and not (
- PyDateTime_Check(ts_input) and
- getattr(ts_input, "tzinfo", None) is None)):
- raise ValueError(
- "Cannot pass fold with possibly unambiguous input: int, "
- "float, numpy.datetime64, str, or timezone-aware "
- "datetime-like. Pass naive datetime-like or build "
- "Timestamp from components."
- )
- if tz is not None and PyTZInfo_Check(tz) and treat_tz_as_pytz(tz):
- raise ValueError(
- "pytz timezones do not support fold. Please use dateutil "
- "timezones."
- )
- if hasattr(ts_input, "fold"):
- ts_input = ts_input.replace(fold=fold)
- # GH 30543 if pd.Timestamp already passed, return it
- # check that only ts_input is passed
- # checking verbosely, because cython doesn't optimize
- # list comprehensions (as of cython 0.29.x)
- if (isinstance(ts_input, _Timestamp) and
- tz is None and unit is None and year is None and
- month is None and day is None and hour is None and
- minute is None and second is None and
- microsecond is None and nanosecond is None and
- tzinfo is None):
- return ts_input
- elif isinstance(ts_input, str):
- # User passed a date string to parse.
- # Check that the user didn't also pass a date attribute kwarg.
- if any(arg is not None for arg in _date_attributes):
- raise ValueError(
- "Cannot pass a date attribute keyword "
- "argument when passing a date string; 'tz' is keyword-only"
- )
- elif ts_input is _no_input:
- # GH 31200
- # When year, month or day is not given, we call the datetime
- # constructor to make sure we get the same error message
- # since Timestamp inherits datetime
- datetime_kwargs = {
- "hour": hour or 0,
- "minute": minute or 0,
- "second": second or 0,
- "microsecond": microsecond or 0,
- "fold": fold or 0
- }
- if year is not None:
- datetime_kwargs["year"] = year
- if month is not None:
- datetime_kwargs["month"] = month
- if day is not None:
- datetime_kwargs["day"] = day
- ts_input = datetime(**datetime_kwargs)
- elif is_integer_object(year):
- # User passed positional arguments:
- # Timestamp(year, month, day[, hour[, minute[, second[,
- # microsecond[, tzinfo]]]]])
- ts_input = datetime(ts_input, year, month, day or 0,
- hour or 0, minute or 0, second or 0, fold=fold or 0)
- unit = None
- if getattr(ts_input, "tzinfo", None) is not None and tz is not None:
- raise ValueError("Cannot pass a datetime or Timestamp with tzinfo with "
- "the tz parameter. Use tz_convert instead.")
- tzobj = maybe_get_tz(tz)
- if tzobj is not None and is_datetime64_object(ts_input):
- # GH#24559, GH#42288 As of 2.0 we treat datetime64 as
- # wall-time (consistent with DatetimeIndex)
- return cls(ts_input).tz_localize(tzobj)
- if nanosecond is None:
- nanosecond = 0
- elif not (999 >= nanosecond >= 0):
- raise ValueError("nanosecond must be in 0..999")
- ts = convert_to_tsobject(ts_input, tzobj, unit, 0, 0, nanosecond)
- if ts.value == NPY_NAT:
- return NaT
- return create_timestamp_from_ts(ts.value, ts.dts, ts.tzinfo, ts.fold, ts.creso)
- def _round(self, freq, mode, ambiguous="raise", nonexistent="raise"):
- cdef:
- int64_t nanos
- freq = to_offset(freq)
- freq.nanos # raises on non-fixed freq
- nanos = delta_to_nanoseconds(freq, self._creso)
- if nanos == 0:
- if freq.nanos == 0:
- raise ValueError("Division by zero in rounding")
- # e.g. self.unit == "s" and sub-second freq
- return self
- # TODO: problem if nanos==0
- if self.tz is not None:
- value = self.tz_localize(None)._value
- else:
- value = self._value
- value = np.array([value], dtype=np.int64)
- # Will only ever contain 1 element for timestamp
- r = round_nsint64(value, mode, nanos)[0]
- result = Timestamp._from_value_and_reso(r, self._creso, None)
- if self.tz is not None:
- result = result.tz_localize(
- self.tz, ambiguous=ambiguous, nonexistent=nonexistent
- )
- return result
- def round(self, freq, ambiguous="raise", nonexistent="raise"):
- """
- Round the Timestamp to the specified resolution.
- Parameters
- ----------
- freq : str
- Frequency string indicating the rounding resolution.
- ambiguous : bool or {'raise', 'NaT'}, default 'raise'
- The behavior is as follows:
- * bool contains flags to determine if time is dst or not (note
- that this flag is only applicable for ambiguous fall dst dates).
- * 'NaT' will return NaT for an ambiguous time.
- * 'raise' will raise an AmbiguousTimeError for an ambiguous time.
- nonexistent : {'raise', 'shift_forward', 'shift_backward, 'NaT', \
- timedelta}, default 'raise'
- A nonexistent time does not exist in a particular timezone
- where clocks moved forward due to DST.
- * 'shift_forward' will shift the nonexistent time forward to the
- closest existing time.
- * 'shift_backward' will shift the nonexistent time backward to the
- closest existing time.
- * 'NaT' will return NaT where there are nonexistent times.
- * timedelta objects will shift nonexistent times by the timedelta.
- * 'raise' will raise an NonExistentTimeError if there are
- nonexistent times.
- Returns
- -------
- a new Timestamp rounded to the given resolution of `freq`
- Raises
- ------
- ValueError if the freq cannot be converted
- Notes
- -----
- If the Timestamp has a timezone, rounding will take place relative to the
- local ("wall") time and re-localized to the same timezone. When rounding
- near daylight savings time, use ``nonexistent`` and ``ambiguous`` to
- control the re-localization behavior.
- Examples
- --------
- Create a timestamp object:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- A timestamp can be rounded using multiple frequency units:
- >>> ts.round(freq='H') # hour
- Timestamp('2020-03-14 16:00:00')
- >>> ts.round(freq='T') # minute
- Timestamp('2020-03-14 15:33:00')
- >>> ts.round(freq='S') # seconds
- Timestamp('2020-03-14 15:32:52')
- >>> ts.round(freq='L') # milliseconds
- Timestamp('2020-03-14 15:32:52.193000')
- ``freq`` can also be a multiple of a single unit, like '5T' (i.e. 5 minutes):
- >>> ts.round(freq='5T')
- Timestamp('2020-03-14 15:35:00')
- or a combination of multiple units, like '1H30T' (i.e. 1 hour and 30 minutes):
- >>> ts.round(freq='1H30T')
- Timestamp('2020-03-14 15:00:00')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.round()
- NaT
- When rounding near a daylight savings time transition, use ``ambiguous`` or
- ``nonexistent`` to control how the timestamp should be re-localized.
- >>> ts_tz = pd.Timestamp("2021-10-31 01:30:00").tz_localize("Europe/Amsterdam")
- >>> ts_tz.round("H", ambiguous=False)
- Timestamp('2021-10-31 02:00:00+0100', tz='Europe/Amsterdam')
- >>> ts_tz.round("H", ambiguous=True)
- Timestamp('2021-10-31 02:00:00+0200', tz='Europe/Amsterdam')
- """
- return self._round(
- freq, RoundTo.NEAREST_HALF_EVEN, ambiguous, nonexistent
- )
- def floor(self, freq, ambiguous="raise", nonexistent="raise"):
- """
- Return a new Timestamp floored to this resolution.
- Parameters
- ----------
- freq : str
- Frequency string indicating the flooring resolution.
- ambiguous : bool or {'raise', 'NaT'}, default 'raise'
- The behavior is as follows:
- * bool contains flags to determine if time is dst or not (note
- that this flag is only applicable for ambiguous fall dst dates).
- * 'NaT' will return NaT for an ambiguous time.
- * 'raise' will raise an AmbiguousTimeError for an ambiguous time.
- nonexistent : {'raise', 'shift_forward', 'shift_backward, 'NaT', \
- timedelta}, default 'raise'
- A nonexistent time does not exist in a particular timezone
- where clocks moved forward due to DST.
- * 'shift_forward' will shift the nonexistent time forward to the
- closest existing time.
- * 'shift_backward' will shift the nonexistent time backward to the
- closest existing time.
- * 'NaT' will return NaT where there are nonexistent times.
- * timedelta objects will shift nonexistent times by the timedelta.
- * 'raise' will raise an NonExistentTimeError if there are
- nonexistent times.
- Raises
- ------
- ValueError if the freq cannot be converted.
- Notes
- -----
- If the Timestamp has a timezone, flooring will take place relative to the
- local ("wall") time and re-localized to the same timezone. When flooring
- near daylight savings time, use ``nonexistent`` and ``ambiguous`` to
- control the re-localization behavior.
- Examples
- --------
- Create a timestamp object:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- A timestamp can be floored using multiple frequency units:
- >>> ts.floor(freq='H') # hour
- Timestamp('2020-03-14 15:00:00')
- >>> ts.floor(freq='T') # minute
- Timestamp('2020-03-14 15:32:00')
- >>> ts.floor(freq='S') # seconds
- Timestamp('2020-03-14 15:32:52')
- >>> ts.floor(freq='N') # nanoseconds
- Timestamp('2020-03-14 15:32:52.192548651')
- ``freq`` can also be a multiple of a single unit, like '5T' (i.e. 5 minutes):
- >>> ts.floor(freq='5T')
- Timestamp('2020-03-14 15:30:00')
- or a combination of multiple units, like '1H30T' (i.e. 1 hour and 30 minutes):
- >>> ts.floor(freq='1H30T')
- Timestamp('2020-03-14 15:00:00')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.floor()
- NaT
- When rounding near a daylight savings time transition, use ``ambiguous`` or
- ``nonexistent`` to control how the timestamp should be re-localized.
- >>> ts_tz = pd.Timestamp("2021-10-31 03:30:00").tz_localize("Europe/Amsterdam")
- >>> ts_tz.floor("2H", ambiguous=False)
- Timestamp('2021-10-31 02:00:00+0100', tz='Europe/Amsterdam')
- >>> ts_tz.floor("2H", ambiguous=True)
- Timestamp('2021-10-31 02:00:00+0200', tz='Europe/Amsterdam')
- """
- return self._round(freq, RoundTo.MINUS_INFTY, ambiguous, nonexistent)
- def ceil(self, freq, ambiguous="raise", nonexistent="raise"):
- """
- Return a new Timestamp ceiled to this resolution.
- Parameters
- ----------
- freq : str
- Frequency string indicating the ceiling resolution.
- ambiguous : bool or {'raise', 'NaT'}, default 'raise'
- The behavior is as follows:
- * bool contains flags to determine if time is dst or not (note
- that this flag is only applicable for ambiguous fall dst dates).
- * 'NaT' will return NaT for an ambiguous time.
- * 'raise' will raise an AmbiguousTimeError for an ambiguous time.
- nonexistent : {'raise', 'shift_forward', 'shift_backward, 'NaT', \
- timedelta}, default 'raise'
- A nonexistent time does not exist in a particular timezone
- where clocks moved forward due to DST.
- * 'shift_forward' will shift the nonexistent time forward to the
- closest existing time.
- * 'shift_backward' will shift the nonexistent time backward to the
- closest existing time.
- * 'NaT' will return NaT where there are nonexistent times.
- * timedelta objects will shift nonexistent times by the timedelta.
- * 'raise' will raise an NonExistentTimeError if there are
- nonexistent times.
- Raises
- ------
- ValueError if the freq cannot be converted.
- Notes
- -----
- If the Timestamp has a timezone, ceiling will take place relative to the
- local ("wall") time and re-localized to the same timezone. When ceiling
- near daylight savings time, use ``nonexistent`` and ``ambiguous`` to
- control the re-localization behavior.
- Examples
- --------
- Create a timestamp object:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- A timestamp can be ceiled using multiple frequency units:
- >>> ts.ceil(freq='H') # hour
- Timestamp('2020-03-14 16:00:00')
- >>> ts.ceil(freq='T') # minute
- Timestamp('2020-03-14 15:33:00')
- >>> ts.ceil(freq='S') # seconds
- Timestamp('2020-03-14 15:32:53')
- >>> ts.ceil(freq='U') # microseconds
- Timestamp('2020-03-14 15:32:52.192549')
- ``freq`` can also be a multiple of a single unit, like '5T' (i.e. 5 minutes):
- >>> ts.ceil(freq='5T')
- Timestamp('2020-03-14 15:35:00')
- or a combination of multiple units, like '1H30T' (i.e. 1 hour and 30 minutes):
- >>> ts.ceil(freq='1H30T')
- Timestamp('2020-03-14 16:30:00')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.ceil()
- NaT
- When rounding near a daylight savings time transition, use ``ambiguous`` or
- ``nonexistent`` to control how the timestamp should be re-localized.
- >>> ts_tz = pd.Timestamp("2021-10-31 01:30:00").tz_localize("Europe/Amsterdam")
- >>> ts_tz.ceil("H", ambiguous=False)
- Timestamp('2021-10-31 02:00:00+0100', tz='Europe/Amsterdam')
- >>> ts_tz.ceil("H", ambiguous=True)
- Timestamp('2021-10-31 02:00:00+0200', tz='Europe/Amsterdam')
- """
- return self._round(freq, RoundTo.PLUS_INFTY, ambiguous, nonexistent)
- @property
- def tz(self):
- """
- Alias for tzinfo.
- Examples
- --------
- >>> ts = pd.Timestamp(1584226800, unit='s', tz='Europe/Stockholm')
- >>> ts.tz
- <DstTzInfo 'Europe/Stockholm' CET+1:00:00 STD>
- """
- return self.tzinfo
- @tz.setter
- def tz(self, value):
- # GH 3746: Prevent localizing or converting the index by setting tz
- raise AttributeError(
- "Cannot directly set timezone. "
- "Use tz_localize() or tz_convert() as appropriate"
- )
- def tz_localize(self, tz, ambiguous="raise", nonexistent="raise"):
- """
- Localize the Timestamp to a timezone.
- Convert naive Timestamp to local time zone or remove
- timezone from timezone-aware Timestamp.
- Parameters
- ----------
- tz : str, pytz.timezone, dateutil.tz.tzfile or None
- Time zone for time which Timestamp will be converted to.
- None will remove timezone holding local time.
- ambiguous : bool, 'NaT', default 'raise'
- When clocks moved backward due to DST, ambiguous times may arise.
- For example in Central European Time (UTC+01), when going from
- 03:00 DST to 02:00 non-DST, 02:30:00 local time occurs both at
- 00:30:00 UTC and at 01:30:00 UTC. In such a situation, the
- `ambiguous` parameter dictates how ambiguous times should be
- handled.
- The behavior is as follows:
- * bool contains flags to determine if time is dst or not (note
- that this flag is only applicable for ambiguous fall dst dates).
- * 'NaT' will return NaT for an ambiguous time.
- * 'raise' will raise an AmbiguousTimeError for an ambiguous time.
- nonexistent : 'shift_forward', 'shift_backward, 'NaT', timedelta, \
- default 'raise'
- A nonexistent time does not exist in a particular timezone
- where clocks moved forward due to DST.
- The behavior is as follows:
- * 'shift_forward' will shift the nonexistent time forward to the
- closest existing time.
- * 'shift_backward' will shift the nonexistent time backward to the
- closest existing time.
- * 'NaT' will return NaT where there are nonexistent times.
- * timedelta objects will shift nonexistent times by the timedelta.
- * 'raise' will raise an NonExistentTimeError if there are
- nonexistent times.
- Returns
- -------
- localized : Timestamp
- Raises
- ------
- TypeError
- If the Timestamp is tz-aware and tz is not None.
- Examples
- --------
- Create a naive timestamp object:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651')
- >>> ts
- Timestamp('2020-03-14 15:32:52.192548651')
- Add 'Europe/Stockholm' as timezone:
- >>> ts.tz_localize(tz='Europe/Stockholm')
- Timestamp('2020-03-14 15:32:52.192548651+0100', tz='Europe/Stockholm')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.tz_localize()
- NaT
- """
- if not isinstance(ambiguous, bool) and ambiguous not in {"NaT", "raise"}:
- raise ValueError(
- "'ambiguous' parameter must be one of: "
- "True, False, 'NaT', 'raise' (default)"
- )
- nonexistent_options = ("raise", "NaT", "shift_forward", "shift_backward")
- if nonexistent not in nonexistent_options and not PyDelta_Check(nonexistent):
- raise ValueError(
- "The nonexistent argument must be one of 'raise', "
- "'NaT', 'shift_forward', 'shift_backward' or a timedelta object"
- )
- if self.tzinfo is None:
- # tz naive, localize
- tz = maybe_get_tz(tz)
- if not isinstance(ambiguous, str):
- ambiguous = [ambiguous]
- value = tz_localize_to_utc_single(self._value, tz,
- ambiguous=ambiguous,
- nonexistent=nonexistent,
- creso=self._creso)
- elif tz is None:
- # reset tz
- value = tz_convert_from_utc_single(self._value, self.tz, creso=self._creso)
- else:
- raise TypeError(
- "Cannot localize tz-aware Timestamp, use tz_convert for conversions"
- )
- out = type(self)._from_value_and_reso(value, self._creso, tz=tz)
- return out
- def tz_convert(self, tz):
- """
- Convert timezone-aware Timestamp to another time zone.
- Parameters
- ----------
- tz : str, pytz.timezone, dateutil.tz.tzfile or None
- Time zone for time which Timestamp will be converted to.
- None will remove timezone holding UTC time.
- Returns
- -------
- converted : Timestamp
- Raises
- ------
- TypeError
- If Timestamp is tz-naive.
- Examples
- --------
- Create a timestamp object with UTC timezone:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651', tz='UTC')
- >>> ts
- Timestamp('2020-03-14 15:32:52.192548651+0000', tz='UTC')
- Change to Tokyo timezone:
- >>> ts.tz_convert(tz='Asia/Tokyo')
- Timestamp('2020-03-15 00:32:52.192548651+0900', tz='Asia/Tokyo')
- Can also use ``astimezone``:
- >>> ts.astimezone(tz='Asia/Tokyo')
- Timestamp('2020-03-15 00:32:52.192548651+0900', tz='Asia/Tokyo')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.tz_convert(tz='Asia/Tokyo')
- NaT
- """
- if self.tzinfo is None:
- # tz naive, use tz_localize
- raise TypeError(
- "Cannot convert tz-naive Timestamp, use tz_localize to localize"
- )
- else:
- # Same UTC timestamp, different time zone
- tz = maybe_get_tz(tz)
- out = type(self)._from_value_and_reso(self._value, reso=self._creso, tz=tz)
- return out
- astimezone = tz_convert
- def replace(
- self,
- year=None,
- month=None,
- day=None,
- hour=None,
- minute=None,
- second=None,
- microsecond=None,
- nanosecond=None,
- tzinfo=object,
- fold=None,
- ):
- """
- Implements datetime.replace, handles nanoseconds.
- Parameters
- ----------
- year : int, optional
- month : int, optional
- day : int, optional
- hour : int, optional
- minute : int, optional
- second : int, optional
- microsecond : int, optional
- nanosecond : int, optional
- tzinfo : tz-convertible, optional
- fold : int, optional
- Returns
- -------
- Timestamp with fields replaced
- Examples
- --------
- Create a timestamp object:
- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651', tz='UTC')
- >>> ts
- Timestamp('2020-03-14 15:32:52.192548651+0000', tz='UTC')
- Replace year and the hour:
- >>> ts.replace(year=1999, hour=10)
- Timestamp('1999-03-14 10:32:52.192548651+0000', tz='UTC')
- Replace timezone (not a conversion):
- >>> import pytz
- >>> ts.replace(tzinfo=pytz.timezone('US/Pacific'))
- Timestamp('2020-03-14 15:32:52.192548651-0700', tz='US/Pacific')
- Analogous for ``pd.NaT``:
- >>> pd.NaT.replace(tzinfo=pytz.timezone('US/Pacific'))
- NaT
- """
- cdef:
- npy_datetimestruct dts
- int64_t value
- object k, v
- datetime ts_input
- tzinfo_type tzobj
- _TSObject ts
- # set to naive if needed
- tzobj = self.tzinfo
- value = self._value
- # GH 37610. Preserve fold when replacing.
- if fold is None:
- fold = self.fold
- if tzobj is not None:
- value = tz_convert_from_utc_single(value, tzobj, creso=self._creso)
- # setup components
- pandas_datetime_to_datetimestruct(value, self._creso, &dts)
- dts.ps = self.nanosecond * 1000
- # replace
- def validate(k, v):
- """ validate integers """
- if not is_integer_object(v):
- raise ValueError(
- f"value must be an integer, received {type(v)} for {k}"
- )
- return v
- if year is not None:
- dts.year = validate("year", year)
- if month is not None:
- dts.month = validate("month", month)
- if day is not None:
- dts.day = validate("day", day)
- if hour is not None:
- dts.hour = validate("hour", hour)
- if minute is not None:
- dts.min = validate("minute", minute)
- if second is not None:
- dts.sec = validate("second", second)
- if microsecond is not None:
- dts.us = validate("microsecond", microsecond)
- if nanosecond is not None:
- dts.ps = validate("nanosecond", nanosecond) * 1000
- if tzinfo is not object:
- tzobj = tzinfo
- # reconstruct & check bounds
- if tzobj is None:
- # We can avoid going through pydatetime paths, which is robust
- # to datetimes outside of pydatetime range.
- ts = _TSObject()
- check_dts_bounds(&dts, self._creso)
- ts.value = npy_datetimestruct_to_datetime(self._creso, &dts)
- ts.dts = dts
- ts.creso = self._creso
- ts.fold = fold
- return create_timestamp_from_ts(
- ts.value, dts, tzobj, fold, reso=self._creso
- )
- elif tzobj is not None and treat_tz_as_pytz(tzobj):
- # replacing across a DST boundary may induce a new tzinfo object
- # see GH#18319
- ts_input = tzobj.localize(datetime(dts.year, dts.month, dts.day,
- dts.hour, dts.min, dts.sec,
- dts.us),
- is_dst=not bool(fold))
- tzobj = ts_input.tzinfo
- else:
- kwargs = {"year": dts.year, "month": dts.month, "day": dts.day,
- "hour": dts.hour, "minute": dts.min, "second": dts.sec,
- "microsecond": dts.us, "tzinfo": tzobj,
- "fold": fold}
- ts_input = datetime(**kwargs)
- ts = convert_datetime_to_tsobject(
- ts_input, tzobj, nanos=dts.ps // 1000, reso=self._creso
- )
- return create_timestamp_from_ts(
- ts.value, dts, tzobj, fold, reso=self._creso
- )
- def to_julian_date(self) -> np.float64:
- """
- Convert TimeStamp to a Julian Date.
- 0 Julian date is noon January 1, 4713 BC.
- Examples
- --------
- >>> ts = pd.Timestamp('2020-03-14T15:32:52')
- >>> ts.to_julian_date()
- 2458923.147824074
- """
- year = self.year
- month = self.month
- day = self.day
- if month <= 2:
- year -= 1
- month += 12
- return (day +
- np.fix((153 * month - 457) / 5) +
- 365 * year +
- np.floor(year / 4) -
- np.floor(year / 100) +
- np.floor(year / 400) +
- 1721118.5 +
- (self.hour +
- self.minute / 60.0 +
- self.second / 3600.0 +
- self.microsecond / 3600.0 / 1e+6 +
- self.nanosecond / 3600.0 / 1e+9
- ) / 24.0)
- def isoweekday(self):
- """
- Return the day of the week represented by the date.
- Monday == 1 ... Sunday == 7.
- """
- # same as super().isoweekday(), but that breaks because of how
- # we have overriden year, see note in create_timestamp_from_ts
- return self.weekday() + 1
- def weekday(self):
- """
- Return the day of the week represented by the date.
- Monday == 0 ... Sunday == 6.
- """
- # same as super().weekday(), but that breaks because of how
- # we have overriden year, see note in create_timestamp_from_ts
- return ccalendar.dayofweek(self.year, self.month, self.day)
- # Aliases
- Timestamp.weekofyear = Timestamp.week
- Timestamp.daysinmonth = Timestamp.days_in_month
- # ----------------------------------------------------------------------
- # Scalar analogues to functions in vectorized.pyx
- @cython.cdivision(False)
- cdef int64_t normalize_i8_stamp(int64_t local_val, int64_t ppd) nogil:
- """
- Round the localized nanosecond timestamp down to the previous midnight.
- Parameters
- ----------
- local_val : int64_t
- ppd : int64_t
- Periods per day in the Timestamp's resolution.
- Returns
- -------
- int64_t
- """
- return local_val - (local_val % ppd)
|