summaryrefslogtreecommitdiffstats
path: root/pendulum/interval.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-17 14:36:26 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-17 14:36:33 +0000
commit665666d6f4213da8db57ebb480947b7caf1fe382 (patch)
tree0cac5d322dfe861a6de62b04fb916cef6dbe4510 /pendulum/interval.py
parentReleasing debian version 3.0.0~a1-2. (diff)
downloadpendulum-665666d6f4213da8db57ebb480947b7caf1fe382.tar.xz
pendulum-665666d6f4213da8db57ebb480947b7caf1fe382.zip
Merging upstream version 3.0.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pendulum/interval.py')
-rw-r--r--pendulum/interval.py448
1 files changed, 0 insertions, 448 deletions
diff --git a/pendulum/interval.py b/pendulum/interval.py
deleted file mode 100644
index f20042b..0000000
--- a/pendulum/interval.py
+++ /dev/null
@@ -1,448 +0,0 @@
-from __future__ import annotations
-
-import operator
-
-from datetime import date
-from datetime import datetime
-from datetime import timedelta
-from typing import TYPE_CHECKING
-from typing import Iterator
-from typing import Union
-from typing import cast
-from typing import overload
-
-import pendulum
-
-from pendulum.constants import MONTHS_PER_YEAR
-from pendulum.duration import Duration
-from pendulum.helpers import precise_diff
-
-if TYPE_CHECKING:
- from typing import SupportsIndex
-
- from pendulum.helpers import PreciseDiff
- from pendulum.locales.locale import Locale # noqa
-
-
-class Interval(Duration):
- """
- A period of time between two datetimes.
- """
-
- @overload
- def __new__(
- cls,
- start: pendulum.DateTime | datetime,
- end: pendulum.DateTime | datetime,
- absolute: bool = False,
- ) -> Interval:
- ...
-
- @overload
- def __new__(
- cls,
- start: pendulum.Date | date,
- end: pendulum.Date | date,
- absolute: bool = False,
- ) -> Interval:
- ...
-
- def __new__(
- cls,
- start: pendulum.DateTime | pendulum.Date | datetime | date,
- end: pendulum.DateTime | pendulum.Date | datetime | date,
- absolute: bool = False,
- ) -> Interval:
- if (
- isinstance(start, datetime)
- and not isinstance(end, datetime)
- or not isinstance(start, datetime)
- and isinstance(end, datetime)
- ):
- raise ValueError("Both start and end of a Period must have the same type")
-
- if (
- isinstance(start, datetime)
- and isinstance(end, datetime)
- and (
- start.tzinfo is None
- and end.tzinfo is not None
- or start.tzinfo is not None
- and end.tzinfo is None
- )
- ):
- raise TypeError("can't compare offset-naive and offset-aware datetimes")
-
- if absolute and start > end:
- end, start = start, end
-
- _start = start
- _end = end
- if isinstance(start, pendulum.DateTime):
- _start = datetime(
- start.year,
- start.month,
- start.day,
- start.hour,
- start.minute,
- start.second,
- start.microsecond,
- tzinfo=start.tzinfo,
- fold=start.fold,
- )
- elif isinstance(start, pendulum.Date):
- _start = date(start.year, start.month, start.day)
-
- if isinstance(end, pendulum.DateTime):
- _end = datetime(
- end.year,
- end.month,
- end.day,
- end.hour,
- end.minute,
- end.second,
- end.microsecond,
- tzinfo=end.tzinfo,
- fold=end.fold,
- )
- elif isinstance(end, pendulum.Date):
- _end = date(end.year, end.month, end.day)
-
- # Fixing issues with datetime.__sub__()
- # not handling offsets if the tzinfo is the same
- if (
- isinstance(_start, datetime)
- and isinstance(_end, datetime)
- and _start.tzinfo is _end.tzinfo
- ):
- if _start.tzinfo is not None:
- offset = cast(timedelta, cast(datetime, start).utcoffset())
- _start = (_start - offset).replace(tzinfo=None)
-
- if isinstance(end, datetime) and _end.tzinfo is not None:
- offset = cast(timedelta, end.utcoffset())
- _end = (_end - offset).replace(tzinfo=None)
-
- delta: timedelta = _end - _start # type: ignore[operator]
-
- return cast(Interval, super().__new__(cls, seconds=delta.total_seconds()))
-
- def __init__(
- self,
- start: pendulum.DateTime | pendulum.Date | datetime | date,
- end: pendulum.DateTime | pendulum.Date | datetime | date,
- absolute: bool = False,
- ) -> None:
- super().__init__()
-
- _start: pendulum.DateTime | pendulum.Date | datetime | date
- if not isinstance(start, pendulum.Date):
- if isinstance(start, datetime):
- start = pendulum.instance(start)
- else:
- start = pendulum.date(start.year, start.month, start.day)
-
- _start = start
- else:
- if isinstance(start, pendulum.DateTime):
- _start = datetime(
- start.year,
- start.month,
- start.day,
- start.hour,
- start.minute,
- start.second,
- start.microsecond,
- tzinfo=start.tzinfo,
- )
- else:
- _start = date(start.year, start.month, start.day)
-
- _end: pendulum.DateTime | pendulum.Date | datetime | date
- if not isinstance(end, pendulum.Date):
- if isinstance(end, datetime):
- end = pendulum.instance(end)
- else:
- end = pendulum.date(end.year, end.month, end.day)
-
- _end = end
- else:
- if isinstance(end, pendulum.DateTime):
- _end = datetime(
- end.year,
- end.month,
- end.day,
- end.hour,
- end.minute,
- end.second,
- end.microsecond,
- tzinfo=end.tzinfo,
- )
- else:
- _end = date(end.year, end.month, end.day)
-
- self._invert = False
- if start > end:
- self._invert = True
-
- if absolute:
- end, start = start, end
- _end, _start = _start, _end
-
- self._absolute = absolute
- self._start: pendulum.DateTime | pendulum.Date = start
- self._end: pendulum.DateTime | pendulum.Date = end
- self._delta: PreciseDiff = precise_diff(_start, _end)
-
- @property
- def years(self) -> int:
- return self._delta.years
-
- @property
- def months(self) -> int:
- return self._delta.months
-
- @property
- def weeks(self) -> int:
- return abs(self._delta.days) // 7 * self._sign(self._delta.days)
-
- @property
- def days(self) -> int:
- return self._days
-
- @property
- def remaining_days(self) -> int:
- return abs(self._delta.days) % 7 * self._sign(self._days)
-
- @property
- def hours(self) -> int:
- return self._delta.hours
-
- @property
- def minutes(self) -> int:
- return self._delta.minutes
-
- @property
- def start(self) -> pendulum.DateTime | pendulum.Date | datetime | date:
- return self._start
-
- @property
- def end(self) -> pendulum.DateTime | pendulum.Date | datetime | date:
- return self._end
-
- def in_years(self) -> int:
- """
- Gives the duration of the Period in full years.
- """
- return self.years
-
- def in_months(self) -> int:
- """
- Gives the duration of the Period in full months.
- """
- return self.years * MONTHS_PER_YEAR + self.months
-
- def in_weeks(self) -> int:
- days = self.in_days()
- sign = 1
-
- if days < 0:
- sign = -1
-
- return sign * (abs(days) // 7)
-
- def in_days(self) -> int:
- return self._delta.total_days
-
- def in_words(self, locale: str | None = None, separator: str = " ") -> str:
- """
- Get the current interval in words in the current locale.
-
- Ex: 6 jours 23 heures 58 minutes
-
- :param locale: The locale to use. Defaults to current locale.
- :param separator: The separator to use between each unit
- """
- from pendulum.locales.locale import Locale # noqa
-
- periods = [
- ("year", self.years),
- ("month", self.months),
- ("week", self.weeks),
- ("day", self.remaining_days),
- ("hour", self.hours),
- ("minute", self.minutes),
- ("second", self.remaining_seconds),
- ]
- loaded_locale: Locale = Locale.load(locale or pendulum.get_locale())
- parts = []
- for period in periods:
- unit, period_count = period
- if abs(period_count) > 0:
- translation = loaded_locale.translation(
- f"units.{unit}.{loaded_locale.plural(abs(period_count))}"
- )
- parts.append(translation.format(period_count))
-
- if not parts:
- count: str | int = 0
- if abs(self.microseconds) > 0:
- unit = f"units.second.{loaded_locale.plural(1)}"
- count = f"{abs(self.microseconds) / 1e6:.2f}"
- else:
- unit = f"units.microsecond.{loaded_locale.plural(0)}"
-
- translation = loaded_locale.translation(unit)
- parts.append(translation.format(count))
-
- return separator.join(parts)
-
- def range(
- self, unit: str, amount: int = 1
- ) -> Iterator[pendulum.DateTime | pendulum.Date]:
- method = "add"
- op = operator.le
- if not self._absolute and self.invert:
- method = "subtract"
- op = operator.ge
-
- start, end = self.start, self.end
-
- i = amount
- while op(start, end):
- yield cast(Union[pendulum.DateTime, pendulum.Date], start)
-
- start = getattr(self.start, method)(**{unit: i})
-
- i += amount
-
- def as_interval(self) -> Duration:
- """
- Return the Period as a Duration.
- """
- return Duration(seconds=self.total_seconds())
-
- def __iter__(self) -> Iterator[pendulum.DateTime | pendulum.Date]:
- return self.range("days")
-
- def __contains__(
- self, item: datetime | date | pendulum.DateTime | pendulum.Date
- ) -> bool:
- return self.start <= item <= self.end
-
- def __add__(self, other: timedelta) -> Duration:
- return self.as_interval().__add__(other)
-
- __radd__ = __add__
-
- def __sub__(self, other: timedelta) -> Duration:
- return self.as_interval().__sub__(other)
-
- def __neg__(self) -> Interval:
- return self.__class__(self.end, self.start, self._absolute)
-
- def __mul__(self, other: int | float) -> Duration:
- return self.as_interval().__mul__(other)
-
- __rmul__ = __mul__
-
- @overload
- def __floordiv__(self, other: timedelta) -> int:
- ...
-
- @overload
- def __floordiv__(self, other: int) -> Duration:
- ...
-
- def __floordiv__(self, other: int | timedelta) -> int | Duration:
- return self.as_interval().__floordiv__(other)
-
- __div__ = __floordiv__ # type: ignore[assignment]
-
- @overload
- def __truediv__(self, other: timedelta) -> float:
- ...
-
- @overload
- def __truediv__(self, other: float) -> Duration:
- ...
-
- def __truediv__(self, other: float | timedelta) -> Duration | float:
- return self.as_interval().__truediv__(other)
-
- def __mod__(self, other: timedelta) -> Duration:
- return self.as_interval().__mod__(other)
-
- def __divmod__(self, other: timedelta) -> tuple[int, Duration]:
- return self.as_interval().__divmod__(other)
-
- def __abs__(self) -> Interval:
- return self.__class__(self.start, self.end, absolute=True)
-
- def __repr__(self) -> str:
- return f"<Period [{self._start} -> {self._end}]>"
-
- def __str__(self) -> str:
- return self.__repr__()
-
- def _cmp(self, other: timedelta) -> int:
- # Only needed for PyPy
- assert isinstance(other, timedelta)
-
- if isinstance(other, Interval):
- other = other.as_timedelta()
-
- td = self.as_timedelta()
-
- return 0 if td == other else 1 if td > other else -1
-
- def _getstate(
- self, protocol: SupportsIndex = 3
- ) -> tuple[
- pendulum.DateTime | pendulum.Date | datetime | date,
- pendulum.DateTime | pendulum.Date | datetime | date,
- bool,
- ]:
- start, end = self.start, self.end
-
- if self._invert and self._absolute:
- end, start = start, end
-
- return start, end, self._absolute
-
- def __reduce__(
- self,
- ) -> tuple[
- type[Interval],
- tuple[
- pendulum.DateTime | pendulum.Date | datetime | date,
- pendulum.DateTime | pendulum.Date | datetime | date,
- bool,
- ],
- ]:
- return self.__reduce_ex__(2)
-
- def __reduce_ex__(
- self, protocol: SupportsIndex
- ) -> tuple[
- type[Interval],
- tuple[
- pendulum.DateTime | pendulum.Date | datetime | date,
- pendulum.DateTime | pendulum.Date | datetime | date,
- bool,
- ],
- ]:
- return self.__class__, self._getstate(protocol)
-
- def __hash__(self) -> int:
- return hash((self.start, self.end, self._absolute))
-
- def __eq__(self, other: object) -> bool:
- if isinstance(other, Interval):
- return (self.start, self.end, self._absolute) == (
- other.start,
- other.end,
- other._absolute,
- )
- else:
- return self.as_interval() == other