summaryrefslogtreecommitdiffstats
path: root/pendulum/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'pendulum/__init__.py')
-rw-r--r--pendulum/__init__.py315
1 files changed, 315 insertions, 0 deletions
diff --git a/pendulum/__init__.py b/pendulum/__init__.py
new file mode 100644
index 0000000..a85ed88
--- /dev/null
+++ b/pendulum/__init__.py
@@ -0,0 +1,315 @@
+from __future__ import absolute_import
+
+import datetime as _datetime
+
+from typing import Optional
+from typing import Union
+
+from .__version__ import __version__
+from .constants import DAYS_PER_WEEK
+from .constants import FRIDAY
+from .constants import HOURS_PER_DAY
+from .constants import MINUTES_PER_HOUR
+from .constants import MONDAY
+from .constants import MONTHS_PER_YEAR
+from .constants import SATURDAY
+from .constants import SECONDS_PER_DAY
+from .constants import SECONDS_PER_HOUR
+from .constants import SECONDS_PER_MINUTE
+from .constants import SUNDAY
+from .constants import THURSDAY
+from .constants import TUESDAY
+from .constants import WEDNESDAY
+from .constants import WEEKS_PER_YEAR
+from .constants import YEARS_PER_CENTURY
+from .constants import YEARS_PER_DECADE
+from .date import Date
+from .datetime import DateTime
+from .duration import Duration
+from .formatting import Formatter
+from .helpers import format_diff
+from .helpers import get_locale
+from .helpers import get_test_now
+from .helpers import has_test_now
+from .helpers import locale
+from .helpers import set_locale
+from .helpers import set_test_now
+from .helpers import test
+from .helpers import week_ends_at
+from .helpers import week_starts_at
+from .parser import parse
+from .period import Period
+from .time import Time
+from .tz import POST_TRANSITION
+from .tz import PRE_TRANSITION
+from .tz import TRANSITION_ERROR
+from .tz import UTC
+from .tz import local_timezone
+from .tz import set_local_timezone
+from .tz import test_local_timezone
+from .tz import timezone
+from .tz import timezones
+from .tz.timezone import Timezone as _Timezone
+from .utils._compat import _HAS_FOLD
+
+
+_TEST_NOW = None # type: Optional[DateTime]
+_LOCALE = "en"
+_WEEK_STARTS_AT = MONDAY
+_WEEK_ENDS_AT = SUNDAY
+
+_formatter = Formatter()
+
+
+def _safe_timezone(obj):
+ # type: (Optional[Union[str, float, _datetime.tzinfo, _Timezone]]) -> _Timezone
+ """
+ Creates a timezone instance
+ from a string, Timezone, TimezoneInfo or integer offset.
+ """
+ if isinstance(obj, _Timezone):
+ return obj
+
+ if obj is None or obj == "local":
+ return local_timezone()
+
+ if isinstance(obj, (int, float)):
+ obj = int(obj * 60 * 60)
+ elif isinstance(obj, _datetime.tzinfo):
+ # pytz
+ if hasattr(obj, "localize"):
+ obj = obj.zone
+ elif obj.tzname(None) == "UTC":
+ return UTC
+ else:
+ offset = obj.utcoffset(None)
+
+ if offset is None:
+ offset = _datetime.timedelta(0)
+
+ obj = int(offset.total_seconds())
+
+ return timezone(obj)
+
+
+# Public API
+def datetime(
+ year, # type: int
+ month, # type: int
+ day, # type: int
+ hour=0, # type: int
+ minute=0, # type: int
+ second=0, # type: int
+ microsecond=0, # type: int
+ tz=UTC, # type: Optional[Union[str, float, _Timezone]]
+ dst_rule=POST_TRANSITION, # type: str
+): # type: (...) -> DateTime
+ """
+ Creates a new DateTime instance from a specific date and time.
+ """
+ if tz is not None:
+ tz = _safe_timezone(tz)
+
+ if not _HAS_FOLD:
+ dt = naive(year, month, day, hour, minute, second, microsecond)
+ else:
+ dt = _datetime.datetime(year, month, day, hour, minute, second, microsecond)
+ if tz is not None:
+ dt = tz.convert(dt, dst_rule=dst_rule)
+
+ return DateTime(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ tzinfo=dt.tzinfo,
+ fold=dt.fold,
+ )
+
+
+def local(
+ year, month, day, hour=0, minute=0, second=0, microsecond=0
+): # type: (int, int, int, int, int, int, int) -> DateTime
+ """
+ Return a DateTime in the local timezone.
+ """
+ return datetime(
+ year, month, day, hour, minute, second, microsecond, tz=local_timezone()
+ )
+
+
+def naive(
+ year, month, day, hour=0, minute=0, second=0, microsecond=0
+): # type: (int, int, int, int, int, int, int) -> DateTime
+ """
+ Return a naive DateTime.
+ """
+ return DateTime(year, month, day, hour, minute, second, microsecond)
+
+
+def date(year, month, day): # type: (int, int, int) -> Date
+ """
+ Create a new Date instance.
+ """
+ return Date(year, month, day)
+
+
+def time(hour, minute=0, second=0, microsecond=0): # type: (int, int, int, int) -> Time
+ """
+ Create a new Time instance.
+ """
+ return Time(hour, minute, second, microsecond)
+
+
+def instance(
+ dt, tz=UTC
+): # type: (_datetime.datetime, Optional[Union[str, _Timezone]]) -> DateTime
+ """
+ Create a DateTime instance from a datetime one.
+ """
+ if not isinstance(dt, _datetime.datetime):
+ raise ValueError("instance() only accepts datetime objects.")
+
+ if isinstance(dt, DateTime):
+ return dt
+
+ tz = dt.tzinfo or tz
+
+ # Checking for pytz/tzinfo
+ if isinstance(tz, _datetime.tzinfo) and not isinstance(tz, _Timezone):
+ # pytz
+ if hasattr(tz, "localize") and tz.zone:
+ tz = tz.zone
+ else:
+ # We have no sure way to figure out
+ # the timezone name, we fallback
+ # on a fixed offset
+ tz = tz.utcoffset(dt).total_seconds() / 3600
+
+ return datetime(
+ dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, tz=tz
+ )
+
+
+def now(tz=None): # type: (Optional[Union[str, _Timezone]]) -> DateTime
+ """
+ Get a DateTime instance for the current date and time.
+ """
+ if has_test_now():
+ test_instance = get_test_now()
+ _tz = _safe_timezone(tz)
+
+ if tz is not None and _tz != test_instance.timezone:
+ test_instance = test_instance.in_tz(_tz)
+
+ return test_instance
+
+ if tz is None or tz == "local":
+ dt = _datetime.datetime.now(local_timezone())
+ elif tz is UTC or tz == "UTC":
+ dt = _datetime.datetime.now(UTC)
+ else:
+ dt = _datetime.datetime.now(UTC)
+ tz = _safe_timezone(tz)
+ dt = tz.convert(dt)
+
+ return DateTime(
+ dt.year,
+ dt.month,
+ dt.day,
+ dt.hour,
+ dt.minute,
+ dt.second,
+ dt.microsecond,
+ tzinfo=dt.tzinfo,
+ fold=dt.fold if _HAS_FOLD else 0,
+ )
+
+
+def today(tz="local"): # type: (Union[str, _Timezone]) -> DateTime
+ """
+ Create a DateTime instance for today.
+ """
+ return now(tz).start_of("day")
+
+
+def tomorrow(tz="local"): # type: (Union[str, _Timezone]) -> DateTime
+ """
+ Create a DateTime instance for today.
+ """
+ return today(tz).add(days=1)
+
+
+def yesterday(tz="local"): # type: (Union[str, _Timezone]) -> DateTime
+ """
+ Create a DateTime instance for today.
+ """
+ return today(tz).subtract(days=1)
+
+
+def from_format(
+ string, fmt, tz=UTC, locale=None, # noqa
+): # type: (str, str, Union[str, _Timezone], Optional[str]) -> DateTime
+ """
+ Creates a DateTime instance from a specific format.
+ """
+ parts = _formatter.parse(string, fmt, now(), locale=locale)
+ if parts["tz"] is None:
+ parts["tz"] = tz
+
+ return datetime(**parts)
+
+
+def from_timestamp(
+ timestamp, tz=UTC
+): # type: (Union[int, float], Union[str, _Timezone]) -> DateTime
+ """
+ Create a DateTime instance from a timestamp.
+ """
+ dt = _datetime.datetime.utcfromtimestamp(timestamp)
+
+ dt = datetime(
+ dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond
+ )
+
+ if tz is not UTC or tz != "UTC":
+ dt = dt.in_timezone(tz)
+
+ return dt
+
+
+def duration(
+ days=0, # type: float
+ seconds=0, # type: float
+ microseconds=0, # type: float
+ milliseconds=0, # type: float
+ minutes=0, # type: float
+ hours=0, # type: float
+ weeks=0, # type: float
+ years=0, # type: float
+ months=0, # type: float
+): # type: (...) -> Duration
+ """
+ Create a Duration instance.
+ """
+ return Duration(
+ days=days,
+ seconds=seconds,
+ microseconds=microseconds,
+ milliseconds=milliseconds,
+ minutes=minutes,
+ hours=hours,
+ weeks=weeks,
+ years=years,
+ months=months,
+ )
+
+
+def period(start, end, absolute=False): # type: (DateTime, DateTime, bool) -> Period
+ """
+ Create a Period instance.
+ """
+ return Period(start, end, absolute=absolute)