Source code for sambat
"""Exact Bikram Sambat (Nepali calendar) dates with the full ``datetime`` API.
``sambat.date`` and ``sambat.datetime`` mirror :class:`datetime.date` and
:class:`datetime.datetime`, with year, month and day in the Bikram Sambat (BS)
calendar. The calendar-independent types (``timedelta``, ``time``, ``tzinfo``,
``timezone`` and ``UTC``) are the standard library's own objects.
Month lengths come from a table of officially published BS years; dates
outside :data:`MINYEAR`..:data:`MAXYEAR` raise ``ValueError`` instead of being
guessed.
Examples:
>>> import sambat
>>> d = sambat.date(2083, 1, 1)
>>> d.to_gregorian()
datetime.date(2026, 4, 14)
>>> d + sambat.timedelta(days=31)
sambat.date(2083, 2, 1)
>>> sambat.timedelta is __import__("datetime").timedelta
True
"""
from __future__ import annotations
import datetime as _dt
from importlib import import_module
from typing import TYPE_CHECKING, Any
from sambat._date import IsoCalendarDate, date
from sambat._datetime import datetime
from sambat._lookup import MAXYEAR, MINYEAR
from sambat._tz import NEPAL_TZ, NepalTimeZone
if TYPE_CHECKING:
from types import ModuleType
try:
from sambat._version import __version__
except ImportError: # pragma: no cover - only when running from a source tree without a build
__version__ = "0.0.0+unknown"
__all__ = [
"MAXYEAR",
"MINYEAR",
"NEPAL_TZ",
"UTC",
"IsoCalendarDate",
"NepalTimeZone",
"__version__",
"date",
"datetime",
"now_np",
"time",
"timedelta",
"timezone",
"today_np",
"tzinfo",
]
time = _dt.time
timedelta = _dt.timedelta
timezone = _dt.timezone
tzinfo = _dt.tzinfo
UTC = _dt.UTC
_SUBMODULES = frozenset({"calendar", "compat", "delta", "fiscal", "locale", "periods", "text"})
[docs]
def today_np() -> date:
"""Return today's BS date in Nepal, whatever the machine's time zone.
Returns:
The current date in ``Asia/Kathmandu``.
"""
return datetime.now(NEPAL_TZ).date()
[docs]
def now_np() -> datetime:
"""Return the current aware BS datetime in Nepal time (``Asia/Kathmandu``).
Returns:
The current datetime with ``tzinfo=NEPAL_TZ``.
"""
return datetime.now(NEPAL_TZ)
def __getattr__(name: str) -> ModuleType | Any:
"""Import public submodules lazily (``sambat.fiscal`` works without an import)."""
if name in _SUBMODULES:
return import_module(f"sambat.{name}")
message = f"module 'sambat' has no attribute {name!r}"
raise AttributeError(message)
def __dir__() -> list[str]:
return sorted({*__all__, *_SUBMODULES})