dycw-utilities 0.111.1__py3-none-any.whl → 0.112.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.111.1
3
+ Version: 0.112.0
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=j1-gk7DzQOb2e2RhnLMwpl11AV5CfMKamy2OkF4La18,60
1
+ utilities/__init__.py,sha256=Xs6R-k_70_fB8zwc0DeYfdK4J8vyyL3G76ApWiuWPGo,60
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
4
4
  utilities/asyncio.py,sha256=41oQUurWMvadFK5gFnaG21hMM0Vmfn2WS6OpC0R9mas,14757
@@ -12,24 +12,24 @@ utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
12
12
  utilities/cryptography.py,sha256=HyOewI20cl3uRXsKivhIaeLVDInQdzgXZGaly7hS5dE,771
13
13
  utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
14
14
  utilities/dataclasses.py,sha256=Q197PVnE_vUMn_SNnqJBCo4eRy4bdHtgMHWRbSJPtFk,26670
15
- utilities/datetime.py,sha256=XrVHvyHyYMBeU2ClC7xJKwB68l-F2ZCmDznyNXS4hT8,36862
15
+ utilities/datetime.py,sha256=OF7jZE702UecnwAbq9D3N-GINpp9gSGoidki1RhimCE,35752
16
16
  utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
17
17
  utilities/errors.py,sha256=BtSNP0JC3ik536ddPyTerLomCRJV9f6kdMe6POz0QHM,361
18
18
  utilities/eventkit.py,sha256=6M5Xu1SzN-juk9PqBHwy5dS-ta7T0qA6SMpDsakOJ0E,13039
19
- utilities/fastapi.py,sha256=uwqOGbGwzIbP-lfm-ApG1ZEN3BA_TDsaiuTghhLmxb8,2413
20
- utilities/fpdf2.py,sha256=zM3gwOYcAfv7P4qhbyvzPmRY4PPAiAQ-ZnPC6I9SZ1M,1832
19
+ utilities/fastapi.py,sha256=y-35at3005jzlNx2wJoiSvB1Ch5bMo30wgU_so3IDdI,2467
20
+ utilities/fpdf2.py,sha256=y1NGXR5chWqLXWpewGV3hlRGMr_5yV1lVRkPBhPEgJI,1843
21
21
  utilities/functions.py,sha256=jgt592voaHNtX56qX0SRvFveVCRmSIxCZmqvpLZCnY8,27305
22
22
  utilities/functools.py,sha256=WrpHt7NLNWSUn9A1Q_ZIWlNaYZOEI4IFKyBG9HO3BC4,1643
23
23
  utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
24
24
  utilities/git.py,sha256=wpt5dZ5Oi5931pN24_VLZYaQOvmR0OcQuVtgHzFUN1k,2359
25
25
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
26
26
  utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
27
- utilities/hypothesis.py,sha256=sLqYcrFn0I3o0R7maqliIERRtAcREk2CKG8rSHY1t5U,46205
27
+ utilities/hypothesis.py,sha256=OpZhPdPmsYWvqMytFDc-G196eODosUzxQSuo-LfMYmM,46262
28
28
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
29
29
  utilities/iterables.py,sha256=2Yy9gZ7BR4LXR4nlX7outFAjd4dpb3lgUo7ji_sdylY,45076
30
30
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
31
  utilities/lightweight_charts.py,sha256=vyVOzarYhBIOZj2xDhqdbP85qbSKUjdc6Au91rc1W4M,2814
32
- utilities/logging.py,sha256=opIwFjGKOYyMntVeCsFNXOmTY2z02hMf2UtCB76SaI4,25142
32
+ utilities/logging.py,sha256=55LVJYd2BKzeTTQr4tG7uSNMDVEgUO56wK4s-rldjrM,25326
33
33
  utilities/loguru.py,sha256=MEMQVWrdECxk1e3FxGzmOf21vWT9j8CAir98SEXFKPA,3809
34
34
  utilities/luigi.py,sha256=fpH9MbxJDuo6-k9iCXRayFRtiVbUtibCJKugf7ygpv0,5988
35
35
  utilities/math.py,sha256=TexfvLCI12d9Sw5_W4pKVBZ3nRr3zk2iPkcEU7xdEWU,26771
@@ -51,7 +51,7 @@ utilities/polars_ols.py,sha256=efhXf0gjrHUpQrvS6a7g8yJQJWf_ATKtJnqqF2inCOU,5680
51
51
  utilities/pqdm.py,sha256=foRytQybmOQ05pjt5LF7ANyzrIa--4ScDE3T2wd31a4,3118
52
52
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  utilities/pydantic.py,sha256=f6qtR5mO2YMuyvNmbaEj5YeD9eGA4YYfb7Bjzh9jUs0,1845
54
- utilities/pyinstrument.py,sha256=ROq2txPwbe2ZUuYJ2IDNbfT97lu2ca0v5_C_yn6sSlM,800
54
+ utilities/pyinstrument.py,sha256=OJFDh4o1CWIa4aYPYURdQjgap_nvP45KUsCEe94rQHY,829
55
55
  utilities/pyrsistent.py,sha256=MoDcAqQGlSNkmlS32DCJLw-cZFAfHB6K9kpox_iyI4k,2512
56
56
  utilities/pytest.py,sha256=85QUax4g2VBBAqAHtM9wekcSLB7_9O8AKFTaCshztL8,7989
57
57
  utilities/pytest_regressions.py,sha256=-SVT9647Dg6-JcdsiaDKXe3NdOmmrvGevLKWwGjxq3c,5088
@@ -76,18 +76,18 @@ utilities/tenacity.py,sha256=1PUvODiBVgeqIh7G5TRt5WWMSqjLYkEqP53itT97WQc,4914
76
76
  utilities/text.py,sha256=hfcBKF22fKT6s_U-ZdP-g5TjFQ0-NrIrQdvIwERWT80,10971
77
77
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
78
78
  utilities/timer.py,sha256=Rkc49KSpHuC8s7vUxGO9DU55U9I6yDKnchsQqrUCVBs,4075
79
- utilities/traceback.py,sha256=KwHPLdEbdj0fFhXo8MBfxcvem8A-VXYDwFMNJ6f0cTM,27328
79
+ utilities/traceback.py,sha256=secexUnBsecfWV4ZuqP1W4pGF3prOeO1CRyJK-8zQDU,27402
80
80
  utilities/types.py,sha256=kVY71hZkcnyYNIlYSse0mLm8yeP3OBkzhDPMME6jXxo,18126
81
81
  utilities/typing.py,sha256=jtc6EiGZGG0E745jo3NeLqo_HdHt7Zdaco3kCAEWIYU,11177
82
- utilities/tzdata.py,sha256=2ZsPmhTVM9Ptrxb4QrWKtKOB9RiH8IOO-A1u7ULdVbg,176
83
- utilities/tzlocal.py,sha256=42BCquGF54oIqIKe5RGziP4K8Nbm3Ey7uqcNn6m5ge8,534
82
+ utilities/tzdata.py,sha256=yCf70NICwAeazN3_JcXhWvRqCy06XJNQ42j7r6gw3HY,1217
83
+ utilities/tzlocal.py,sha256=3upDNFBvGh1l9njmLR2z2S6K6VxQSb7QizYGUbAH3JU,960
84
84
  utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
85
85
  utilities/version.py,sha256=QFuyEeQA6jI0ruBEcmhqG36f-etg1AEiD1drBBqhQrs,5358
86
86
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
87
- utilities/whenever.py,sha256=TjoTAJ1R27-rKXiXzdE4GzPidmYqm0W58XydDXp-QZM,17786
87
+ utilities/whenever.py,sha256=iLRP_-8CZtBpHKbGZGu-kjSMg1ZubJ-VSmgSy7Eudxw,17787
88
88
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
89
- utilities/zoneinfo.py,sha256=-DQz5a0Ikw9jfSZtL0BEQkXOMC9yGn_xiJYNCLMiqEc,1989
90
- dycw_utilities-0.111.1.dist-info/METADATA,sha256=kXoTkJKsgrfBYD5eCwE45d4mGIX5CMZhVeNHh9SRiL8,13004
91
- dycw_utilities-0.111.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.111.1.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.111.1.dist-info/RECORD,,
89
+ utilities/zoneinfo.py,sha256=-Xm57PMMwDTYpxJdkiJG13wnbwK--I7XItBh5WVhD-o,1874
90
+ dycw_utilities-0.112.0.dist-info/METADATA,sha256=GWKYE-rIVvmMBNyTnfCxMJNqV6PHKYsmLVs-6YJadKw,13004
91
+ dycw_utilities-0.112.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.112.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.112.0.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.111.1"
3
+ __version__ = "0.112.0"
utilities/datetime.py CHANGED
@@ -23,13 +23,7 @@ from utilities.platform import SYSTEM
23
23
  from utilities.sentinel import Sentinel, sentinel
24
24
  from utilities.types import MaybeStr
25
25
  from utilities.typing import is_instance_gen
26
- from utilities.zoneinfo import (
27
- UTC,
28
- HongKong,
29
- Tokyo,
30
- ensure_time_zone,
31
- get_time_zone_name,
32
- )
26
+ from utilities.zoneinfo import UTC, ensure_time_zone, get_time_zone_name
33
27
 
34
28
  if TYPE_CHECKING:
35
29
  from collections.abc import Iterator
@@ -525,28 +519,6 @@ def get_now(*, time_zone: TimeZoneLike = UTC) -> dt.datetime:
525
519
  NOW_UTC = get_now(time_zone=UTC)
526
520
 
527
521
 
528
- def get_now_hk() -> dt.datetime:
529
- """Get the current time in Hong Kong."""
530
- return dt.datetime.now(tz=HongKong)
531
-
532
-
533
- NOW_HK = get_now_hk()
534
-
535
-
536
- def get_now_local() -> dt.datetime:
537
- """Get the current time in local."""
538
- return get_now(time_zone="local")
539
- # don't define `NOW_LOCAL` as this would require `tzlocal`
540
-
541
-
542
- def get_now_tokyo() -> dt.datetime:
543
- """Get the current time in Tokyo."""
544
- return dt.datetime.now(tz=Tokyo)
545
-
546
-
547
- NOW_TOKYO = get_now_tokyo()
548
-
549
-
550
522
  ##
551
523
 
552
524
 
@@ -570,27 +542,6 @@ def get_today(*, time_zone: TimeZoneLike = UTC) -> dt.date:
570
542
  TODAY_UTC = get_today(time_zone=UTC)
571
543
 
572
544
 
573
- def get_today_hk() -> dt.date:
574
- """Get the current date in Hong Kong."""
575
- return get_now_hk().date()
576
-
577
-
578
- TODAY_HK = get_today_hk()
579
-
580
-
581
- def get_today_local() -> dt.date:
582
- """Get the current, timezone-aware local date."""
583
- return get_now_local().date()
584
-
585
-
586
- def get_today_tokyo() -> dt.date:
587
- """Get the current date in Tokyo."""
588
- return get_now_tokyo().date()
589
-
590
-
591
- TODAY_TOKYO = get_today_tokyo()
592
-
593
-
594
545
  ##
595
546
 
596
547
 
@@ -1279,13 +1230,9 @@ __all__ = [
1279
1230
  "MIN_DATE_TWO_DIGIT_YEAR",
1280
1231
  "MIN_MONTH",
1281
1232
  "MONTH",
1282
- "NOW_HK",
1283
- "NOW_TOKYO",
1284
1233
  "NOW_UTC",
1285
1234
  "QUARTER",
1286
1235
  "SECOND",
1287
- "TODAY_HK",
1288
- "TODAY_TOKYO",
1289
1236
  "TODAY_UTC",
1290
1237
  "WEEK",
1291
1238
  "YEAR",
@@ -1335,14 +1282,8 @@ __all__ = [
1335
1282
  "get_half_years",
1336
1283
  "get_months",
1337
1284
  "get_now",
1338
- "get_now_hk",
1339
- "get_now_local",
1340
- "get_now_tokyo",
1341
1285
  "get_quarters",
1342
1286
  "get_today",
1343
- "get_today_hk",
1344
- "get_today_local",
1345
- "get_today_tokyo",
1346
1287
  "get_years",
1347
1288
  "is_integral_timedelta",
1348
1289
  "is_local_datetime",
utilities/fastapi.py CHANGED
@@ -7,7 +7,7 @@ from fastapi import FastAPI
7
7
  from uvicorn import Config, Server
8
8
 
9
9
  from utilities.asyncio import AsyncService
10
- from utilities.datetime import SECOND, datetime_duration_to_float, get_now_local
10
+ from utilities.datetime import SECOND, datetime_duration_to_float
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from utilities.types import Duration
@@ -26,6 +26,7 @@ class _PingerReceiverApp(FastAPI):
26
26
 
27
27
  @self.get("/ping") # skipif-ci
28
28
  def ping() -> str:
29
+ from utilities.tzlocal import get_now_local # skipif-ci
29
30
  from utilities.whenever import serialize_zoned_datetime # skipif-ci
30
31
 
31
32
  now = serialize_zoned_datetime(get_now_local()) # skipif-ci
utilities/fpdf2.py CHANGED
@@ -6,8 +6,6 @@ from typing import TYPE_CHECKING, override
6
6
  from fpdf import FPDF
7
7
  from fpdf.enums import XPos, YPos
8
8
 
9
- from utilities.datetime import get_now_local
10
-
11
9
  if TYPE_CHECKING:
12
10
  from collections.abc import Iterator
13
11
 
@@ -45,6 +43,8 @@ def yield_pdf(*, header: str | None = None) -> Iterator[_BasePDF]:
45
43
 
46
44
  @override
47
45
  def footer(self) -> None:
46
+ from utilities.tzlocal import get_now_local
47
+
48
48
  self.set_y(-15)
49
49
  self.set_font(family="Helvetica", style="I", size=8)
50
50
  page_no, now = self.page_no(), get_now_local()
utilities/hypothesis.py CHANGED
@@ -69,7 +69,6 @@ from utilities.datetime import (
69
69
  date_to_month,
70
70
  datetime_duration_to_float,
71
71
  datetime_duration_to_timedelta,
72
- get_now_local,
73
72
  round_datetime,
74
73
  )
75
74
  from utilities.functions import ensure_int, ensure_str, max_nullable, min_nullable
@@ -1440,6 +1439,7 @@ def yield_test_redis(data: DataObject, /) -> AbstractAsyncContextManager[_TestRe
1440
1439
  from redis.exceptions import ResponseError # skipif-ci-and-not-linux
1441
1440
 
1442
1441
  from utilities.redis import _TestRedis, yield_redis # skipif-ci-and-not-linux
1442
+ from utilities.tzlocal import get_now_local # skipif-ci-and-not-linux
1443
1443
 
1444
1444
  now = get_now_local() # skipif-ci-and-not-linux
1445
1445
  uuid = data.draw(uuids()) # skipif-ci-and-not-linux
utilities/logging.py CHANGED
@@ -37,11 +37,9 @@ from typing import (
37
37
  override,
38
38
  )
39
39
 
40
- from utilities.atomicwrites import move_many, writer
41
40
  from utilities.dataclasses import replace_non_sentinel
42
41
  from utilities.datetime import (
43
42
  SECOND,
44
- get_now_local,
45
43
  maybe_sub_pct_y,
46
44
  parse_datetime_compact,
47
45
  round_datetime,
@@ -200,6 +198,8 @@ def _compute_rollover_actions(
200
198
  patterns: _RolloverPatterns | None = None,
201
199
  backup_count: int = 1,
202
200
  ) -> _RolloverActions:
201
+ from utilities.tzlocal import get_now_local # skipif-ci-and-windows
202
+
203
203
  patterns = ( # skipif-ci-and-windows
204
204
  _compute_rollover_patterns(stem, suffix) if patterns is None else patterns
205
205
  )
@@ -244,6 +244,8 @@ class _RolloverActions:
244
244
  rotations: set[_Rotation] = field(default_factory=set)
245
245
 
246
246
  def do(self) -> None:
247
+ from utilities.atomicwrites import move_many # skipif-ci-and-windows
248
+
247
249
  for deletion in self.deletions: # skipif-ci-and-windows
248
250
  deletion.delete()
249
251
  move_many( # skipif-ci-and-windows
@@ -388,6 +390,9 @@ class StandaloneFileHandler(Handler):
388
390
 
389
391
  @override
390
392
  def emit(self, record: LogRecord) -> None:
393
+ from utilities.atomicwrites import writer
394
+ from utilities.tzlocal import get_now_local
395
+
391
396
  try:
392
397
  path = (
393
398
  resolve_path(path=self._path)
utilities/pyinstrument.py CHANGED
@@ -6,8 +6,9 @@ from typing import TYPE_CHECKING
6
6
 
7
7
  from pyinstrument.profiler import Profiler
8
8
 
9
- from utilities.datetime import get_now_local, serialize_compact
9
+ from utilities.datetime import serialize_compact
10
10
  from utilities.pathlib import PWD
11
+ from utilities.tzlocal import get_now_local
11
12
 
12
13
  if TYPE_CHECKING:
13
14
  from collections.abc import Iterator
utilities/traceback.py CHANGED
@@ -26,7 +26,6 @@ from typing import (
26
26
  runtime_checkable,
27
27
  )
28
28
 
29
- from utilities.datetime import get_now_local
30
29
  from utilities.errors import ImpossibleCaseError
31
30
  from utilities.functions import (
32
31
  ensure_not_none,
@@ -44,10 +43,8 @@ from utilities.reprlib import (
44
43
  RICH_MAX_STRING,
45
44
  RICH_MAX_WIDTH,
46
45
  )
47
- from utilities.rich import yield_call_args_repr, yield_mapping_repr
48
46
  from utilities.types import TBaseException, TCallable
49
47
  from utilities.version import get_version
50
- from utilities.whenever import serialize_zoned_datetime
51
48
 
52
49
  if TYPE_CHECKING:
53
50
  from collections.abc import Callable, Iterable, Iterator
@@ -192,6 +189,8 @@ class _CallArgs:
192
189
  @classmethod
193
190
  def create(cls, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Self:
194
191
  """Make the initial trace data."""
192
+ from utilities.rich import yield_call_args_repr
193
+
195
194
  sig = signature(func)
196
195
  try:
197
196
  bound_args = sig.bind(*args, **kwargs)
@@ -428,6 +427,8 @@ class _Frame:
428
427
  depth: int = 0,
429
428
  ) -> str:
430
429
  """Format the traceback."""
430
+ from utilities.rich import yield_call_args_repr, yield_mapping_repr
431
+
431
432
  lines: list[str] = [f"Frame {index + 1}/{total}: {self.name} ({self.module})"]
432
433
  if detail:
433
434
  lines.append(indent("Inputs:", _INDENT))
@@ -784,6 +785,9 @@ def _yield_header_lines(
784
785
  *, version: MaybeCallableVersionLike | None = None
785
786
  ) -> Iterator[str]:
786
787
  """Yield the header lines."""
788
+ from utilities.tzlocal import get_now_local
789
+ from utilities.whenever import serialize_zoned_datetime
790
+
787
791
  yield f"Date/time | {serialize_zoned_datetime(get_now_local())}"
788
792
  yield f"User | {getuser()}"
789
793
  yield f"Host | {gethostname()}"
utilities/tzdata.py CHANGED
@@ -1,9 +1,63 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import TYPE_CHECKING
3
4
  from zoneinfo import ZoneInfo
4
5
 
6
+ from utilities.datetime import get_now, get_today
7
+
8
+ if TYPE_CHECKING:
9
+ import datetime as dt
10
+
11
+
12
+ HongKong = ZoneInfo("Asia/Hong_Kong")
13
+ Tokyo = ZoneInfo("Asia/Tokyo")
5
14
  USCentral = ZoneInfo("US/Central")
6
15
  USEastern = ZoneInfo("US/Eastern")
7
16
 
8
17
 
9
- __all__ = ["USCentral", "USEastern"]
18
+ def get_now_hong_kong() -> dt.datetime:
19
+ """Get the current time in Hong Kong."""
20
+ return get_now(time_zone=HongKong)
21
+
22
+
23
+ NOW_HONG_KONG = get_now_hong_kong()
24
+
25
+
26
+ def get_now_tokyo() -> dt.datetime:
27
+ """Get the current time in Tokyo."""
28
+ return get_now(time_zone=Tokyo)
29
+
30
+
31
+ NOW_TOKYO = get_now_tokyo()
32
+
33
+
34
+ def get_today_hong_kong() -> dt.date:
35
+ """Get the current date in Hong Kong."""
36
+ return get_today(time_zone=HongKong)
37
+
38
+
39
+ TODAY_HONG_KONG = get_today_hong_kong()
40
+
41
+
42
+ def get_today_tokyo() -> dt.date:
43
+ """Get the current date in Tokyo."""
44
+ return get_today(time_zone=Tokyo)
45
+
46
+
47
+ TODAY_TOKYO = get_today_tokyo()
48
+
49
+
50
+ __all__ = [
51
+ "NOW_HONG_KONG",
52
+ "NOW_TOKYO",
53
+ "TODAY_HONG_KONG",
54
+ "TODAY_TOKYO",
55
+ "HongKong",
56
+ "Tokyo",
57
+ "USCentral",
58
+ "USEastern",
59
+ "get_now_hong_kong",
60
+ "get_now_tokyo",
61
+ "get_today_hong_kong",
62
+ "get_today_tokyo",
63
+ ]
utilities/tzlocal.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import datetime as dt
3
4
  from logging import getLogger
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -19,4 +20,26 @@ def get_local_time_zone() -> ZoneInfo:
19
20
  return time_zone
20
21
 
21
22
 
22
- __all__ = ["get_local_time_zone"]
23
+ def get_now_local() -> dt.datetime:
24
+ """Get the current local time."""
25
+ return dt.datetime.now(tz=get_local_time_zone())
26
+
27
+
28
+ NOW_LOCAL = get_now_local()
29
+
30
+
31
+ def get_today_local() -> dt.date:
32
+ """Get the current, timezone-aware local date."""
33
+ return get_now_local().date()
34
+
35
+
36
+ TODAY_LOCAL = get_today_local()
37
+
38
+
39
+ __all__ = [
40
+ "NOW_LOCAL",
41
+ "TODAY_LOCAL",
42
+ "get_local_time_zone",
43
+ "get_now_local",
44
+ "get_today_local",
45
+ ]
utilities/whenever.py CHANGED
@@ -36,6 +36,7 @@ if TYPE_CHECKING:
36
36
  TimeLike,
37
37
  )
38
38
 
39
+
39
40
  MAX_SERIALIZABLE_TIMEDELTA = dt.timedelta(days=3659635, microseconds=-1)
40
41
  MIN_SERIALIZABLE_TIMEDELTA = -MAX_SERIALIZABLE_TIMEDELTA
41
42
 
utilities/zoneinfo.py CHANGED
@@ -8,10 +8,10 @@ from zoneinfo import ZoneInfo
8
8
  if TYPE_CHECKING:
9
9
  from utilities.types import TimeZone, TimeZoneLike
10
10
 
11
- HongKong = ZoneInfo("Asia/Hong_Kong")
12
- Tokyo = ZoneInfo("Asia/Tokyo")
11
+
13
12
  UTC = ZoneInfo("UTC")
14
13
 
14
+
15
15
  ##
16
16
 
17
17
 
@@ -68,11 +68,4 @@ def get_time_zone_name(time_zone: TimeZoneLike, /) -> TimeZone:
68
68
  return cast("TimeZone", ensure_time_zone(time_zone).key)
69
69
 
70
70
 
71
- __all__ = [
72
- "UTC",
73
- "EnsureTimeZoneError",
74
- "HongKong",
75
- "Tokyo",
76
- "ensure_time_zone",
77
- "get_time_zone_name",
78
- ]
71
+ __all__ = ["UTC", "EnsureTimeZoneError", "ensure_time_zone", "get_time_zone_name"]