Skip to content

Commit e52953f

Browse files
committed
Add a create() method to the DateTime class to ease inheritance
1 parent 5bb730c commit e52953f

File tree

2 files changed

+87
-54
lines changed

2 files changed

+87
-54
lines changed

pendulum/__init__.py

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -107,26 +107,17 @@ def datetime(
107107
"""
108108
Creates a new DateTime instance from a specific date and time.
109109
"""
110-
if tz is not None:
111-
tz = _safe_timezone(tz)
112-
113-
dt = _datetime.datetime(
114-
year, month, day, hour, minute, second, microsecond, fold=fold
115-
)
116-
117-
if tz is not None:
118-
dt = tz.convert(dt, raise_on_unknown_times=raise_on_unknown_times)
119-
120-
return DateTime(
121-
dt.year,
122-
dt.month,
123-
dt.day,
124-
dt.hour,
125-
dt.minute,
126-
dt.second,
127-
dt.microsecond,
128-
tzinfo=dt.tzinfo,
129-
fold=dt.fold,
110+
return DateTime.create(
111+
year,
112+
month,
113+
day,
114+
hour=hour,
115+
minute=minute,
116+
second=second,
117+
microsecond=microsecond,
118+
tz=tz,
119+
fold=fold,
120+
raise_on_unknown_times=raise_on_unknown_times,
130121
)
131122

132123

@@ -211,35 +202,7 @@ def now(tz: Optional[Union[str, Timezone]] = None) -> DateTime:
211202
"""
212203
Get a DateTime instance for the current date and time.
213204
"""
214-
if has_test_now():
215-
test_instance = get_test_now()
216-
_tz = _safe_timezone(tz)
217-
218-
if tz is not None and _tz != test_instance.timezone:
219-
test_instance = test_instance.in_tz(_tz)
220-
221-
return test_instance
222-
223-
if tz is None or tz == "local":
224-
dt = _datetime.datetime.now(local_timezone())
225-
elif tz is UTC or tz == "UTC":
226-
dt = _datetime.datetime.now(UTC)
227-
else:
228-
dt = _datetime.datetime.now(UTC)
229-
tz = _safe_timezone(tz)
230-
dt = dt.astimezone(tz)
231-
232-
return DateTime(
233-
dt.year,
234-
dt.month,
235-
dt.day,
236-
dt.hour,
237-
dt.minute,
238-
dt.second,
239-
dt.microsecond,
240-
tzinfo=dt.tzinfo,
241-
fold=dt.fold,
242-
)
205+
return DateTime.now(tz)
243206

244207

245208
def today(tz: Union[str, Timezone] = "local") -> DateTime:

pendulum/datetime.py

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030
from .date import Date
3131
from .exceptions import PendulumException
3232
from .helpers import add_duration
33+
from .helpers import get_test_now
34+
from .helpers import has_test_now
3335
from .period import Period
3436
from .time import Time
3537
from .tz import UTC
38+
from .tz import local_timezone
3639
from .tz.timezone import FixedTimezone
3740
from .tz.timezone import Timezone
3841
from .utils._compat import PY38
@@ -72,12 +75,79 @@ class DateTime(datetime.datetime, Date):
7275
"century",
7376
]
7477

78+
@classmethod
79+
def create(
80+
cls,
81+
year: int,
82+
month: int,
83+
day: int,
84+
hour: int = 0,
85+
minute: int = 0,
86+
second: int = 0,
87+
microsecond: int = 0,
88+
tz: Optional[Union[str, float, Timezone]] = UTC,
89+
fold: Optional[int] = 1,
90+
raise_on_unknown_times: bool = False,
91+
) -> "DateTime":
92+
"""
93+
Creates a new DateTime instance from a specific date and time.
94+
"""
95+
if tz is not None:
96+
tz = pendulum._safe_timezone(tz)
97+
98+
dt = datetime.datetime(
99+
year, month, day, hour, minute, second, microsecond, fold=fold
100+
)
101+
102+
if tz is not None:
103+
dt = tz.convert(dt, raise_on_unknown_times=raise_on_unknown_times)
104+
105+
return cls(
106+
dt.year,
107+
dt.month,
108+
dt.day,
109+
dt.hour,
110+
dt.minute,
111+
dt.second,
112+
dt.microsecond,
113+
tzinfo=dt.tzinfo,
114+
fold=dt.fold,
115+
)
116+
75117
@classmethod
76118
def now(cls, tz: Optional[Union[str, Timezone]] = None) -> "DateTime":
77119
"""
78120
Get a DateTime instance for the current date and time.
79121
"""
80-
return pendulum.now(tz)
122+
if has_test_now():
123+
test_instance = get_test_now()
124+
_tz = pendulum._safe_timezone(tz)
125+
126+
if tz is not None and _tz != test_instance.timezone:
127+
test_instance = test_instance.in_tz(_tz)
128+
129+
return test_instance
130+
131+
if tz is None or tz == "local":
132+
dt = datetime.datetime.now(local_timezone())
133+
elif tz is UTC or tz == "UTC":
134+
dt = datetime.datetime.now(UTC)
135+
else:
136+
dt = datetime.datetime.now(UTC)
137+
tz = pendulum._safe_timezone(tz)
138+
dt = dt.astimezone(tz)
139+
140+
return cls(
141+
dt.year,
142+
dt.month,
143+
dt.day,
144+
dt.hour,
145+
dt.minute,
146+
dt.second,
147+
dt.microsecond,
148+
tzinfo=dt.tzinfo,
149+
fold=dt.fold,
150+
)
81151

82152
@classmethod
83153
def utcnow(cls) -> "DateTime":
@@ -124,7 +194,7 @@ def set(
124194
if tz is None:
125195
tz = self.tz
126196

127-
return pendulum.datetime(
197+
return DateTime.create(
128198
year, month, day, hour, minute, second, microsecond, tz=tz
129199
)
130200

@@ -428,7 +498,7 @@ def is_long_year(self) -> bool:
428498
See link `https://en.wikipedia.org/wiki/ISO_8601#Week_dates`_
429499
"""
430500
return (
431-
pendulum.datetime(self.year, 12, 28, 0, 0, 0, tz=self.tz).isocalendar()[1]
501+
DateTime.create(self.year, 12, 28, 0, 0, 0, tz=self.tz).isocalendar()[1]
432502
== 53
433503
)
434504

@@ -502,7 +572,7 @@ def add(
502572
)
503573

504574
if units_of_variable_length or self.tzinfo is None:
505-
return pendulum.datetime(
575+
return DateTime.create(
506576
dt.year,
507577
dt.month,
508578
dt.day,
@@ -1225,7 +1295,7 @@ def replace(
12251295
if fold is None:
12261296
fold = self.fold
12271297

1228-
return pendulum.datetime(
1298+
return DateTime.create(
12291299
year, month, day, hour, minute, second, microsecond, tz=tzinfo, fold=fold
12301300
)
12311301

0 commit comments

Comments
 (0)