Spaces:
Runtime error
Runtime error
| from box.timer import Timer | |
| from datetime import datetime, timezone | |
| from zoneinfo import ZoneInfo | |
| from box.ic import ic | |
| from box.color import Code | |
| # from .error import handler | |
| timer = Timer() | |
| import rich | |
| console = rich.get_console() | |
| # PEP 696, disallowing naive datetime objects via type annotations | |
| # | |
| # [1] https://github.com/python/mypy/issues/10067 - I want to be able to declare "naive datetime" or "aware datetime" as types | |
| # [2] https://discuss.python.org/t/pep-696-type-defaults-for-typevarlikes/22569 | |
| # considerations: | |
| # | |
| # [1] datetime.now() is not timezone aware | |
| # [2] str(datetime) is not ISO 8601 compliant, e.g. `2021-08-31 12:34:56` instead of `2021-08-31T12:34:56` | |
| # [3] datetime.now(...) has microsecond precision, which is verbose for log files | |
| # BLACKLIST: datetime.now(), str(datetime) | |
| # convert : dt.astimezone(ZoneInfo("Asia/Kolkata")) | |
| # epoch : int(dt.timestamp()) | |
| # string : dt.isoformat() | |
| # is_naive: dt.tzinfo is None | |
| # timezones: | |
| # | |
| # timezone.utc | |
| # ZoneInfo("Asia/Kolkata") | |
| # ZoneInfo("UTC") | |
| # | |
| # to get the local timezone in a cross-platform way, you can use the tzlocal module | |
| def print_datetime_flaws(): | |
| ic(datetime.now()) | |
| print("... now() is not timezone-aware\n") | |
| ic(str(datetime.now())) | |
| print("... str() missing 'T' and timezone or 'Z\n'") | |
| ic(datetime.now().isoformat()) | |
| print("... isoformat() is verbose, includes microseconds, and missing timezone\n") | |
| ic(datetime.now(ZoneInfo("Asia/Kolkata"))) | |
| print("... missing 'T'\n") | |
| ic(datetime.now(ZoneInfo("UTC")).isoformat()) | |
| ic(datetime.now(ZoneInfo("Asia/Kolkata")).isoformat()) | |
| print("... valid\n") | |
| print(".fromisoformat():") | |
| ic(datetime.fromisoformat(str(datetime.now()))) | |
| ic(datetime.fromisoformat(str(datetime.now().isoformat()))) | |
| ic(datetime.fromisoformat("2024-08-18 16:54:26.331658+00:00")) | |
| print("datetime.fromisoformat(2024-08-18 16:54:26.331658Z)" + (Code.LIGHTRED_EX + " ERROR")) | |
| def get_now(zone: str): # for IST, use "Asia/Kolkata" | |
| return datetime.now(ZoneInfo(zone)).replace(microsecond=0) | |
| def foo(): | |
| dt = DateTimeTZ.now(ZoneInfo("Asia/Kolkata")) | |
| ic(dt.astimezone(ZoneInfo("UTC"))) | |
| ic(int(dt.timestamp())) | |
| ic(dt.isoformat()) | |
| epoch = 1722394690 | |
| epoch.bit_count | |
| x = 1 | |
| y = { "zero": 0 } | |
| print(x/y["zero"]) | |
| class DateTimeTZ(datetime): | |
| """ | |
| A subclass of datetime.datetime that requires all instances to be timezone-aware. | |
| """ | |
| def __new__(cls, *args, **kwargs): | |
| # Create the datetime instance | |
| dt = super().__new__(cls, *args, **kwargs) | |
| # Check if tzinfo is None or not | |
| if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None: | |
| raise ValueError("Datetime object must be timezone-aware") | |
| return dt | |
| def now(cls, tz): # pyright: ignore[reportIncompatibleMethodOverride] | |
| return super().now(tz=tz) | |
| def from_datetime(cls, dt: datetime): | |
| return cls(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo) | |
| if __name__ == "__main__": | |
| try: | |
| # foo() | |
| print_datetime_flaws() | |
| except Exception as e: | |
| # handler(e) | |
| console.print_exception(show_locals=True, extra_lines=0) | |