Skip to content

Commit ca26531

Browse files
authored
Improve performance of from_ordinal of temporal types. (#1046)
Speeds up the function by about a factor of 100 (depending on the exact ordinal chose). Signed-off-by: Grant Lodge <6323995+thelonelyvulpes@users.noreply.github.com>
1 parent 638c05f commit ca26531

File tree

1 file changed

+7
-40
lines changed

1 file changed

+7
-40
lines changed

src/neo4j/time/__init__.py

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -854,35 +854,10 @@ def from_ordinal(cls, ordinal: int) -> Date:
854854
"""
855855
if ordinal == 0:
856856
return ZeroDate
857-
if ordinal >= 736695:
858-
year = 2018 # Project release year
859-
month = 1
860-
day = int(ordinal - 736694)
861-
elif ordinal >= 719163:
862-
year = 1970 # Unix epoch
863-
month = 1
864-
day = int(ordinal - 719162)
865-
else:
866-
year = 1
867-
month = 1
868-
day = int(ordinal)
869-
if day < 1 or day > 3652059:
870-
# Note: this requires a maximum of 22 bits for storage
871-
# Could be transferred in 3 bytes.
872-
raise ValueError("Ordinal out of range (1..3652059)")
873-
if year < MIN_YEAR or year > MAX_YEAR:
874-
raise ValueError("Year out of range (%d..%d)" % (MIN_YEAR, MAX_YEAR))
875-
days_in_year = DAYS_IN_YEAR[year]
876-
while day > days_in_year:
877-
day -= days_in_year
878-
year += 1
879-
days_in_year = DAYS_IN_YEAR[year]
880-
days_in_month = DAYS_IN_MONTH[(year, month)]
881-
while day > days_in_month:
882-
day -= days_in_month
883-
month += 1
884-
days_in_month = DAYS_IN_MONTH[(year, month)]
885-
year, month, day = _normalize_day(year, month, day)
857+
elif ordinal < 0 or ordinal > 3652059:
858+
raise ValueError("Ordinal out of range (0..3652059)")
859+
d = datetime.fromordinal(ordinal)
860+
year, month, day = _normalize_day(d.year, d.month, d.day)
886861
return cls.__new(ordinal, year, month, day)
887862

888863
@classmethod
@@ -1165,17 +1140,9 @@ def __add__(self, other: Duration) -> Date: # type: ignore[override]
11651140
:raises ValueError: if the added duration has a time component.
11661141
"""
11671142
def add_months(d, months):
1168-
years, months = symmetric_divmod(months, 12)
1169-
year = d.__year + years
1170-
month = d.__month + months
1171-
while month > 12:
1172-
year += 1
1173-
month -= 12
1174-
while month < 1:
1175-
year -= 1
1176-
month += 12
1177-
d.__year = year
1178-
d.__month = month
1143+
overflow_years, month = divmod(months + d.__month - 1, 12)
1144+
d.__year += overflow_years
1145+
d.__month = month + 1
11791146

11801147
def add_days(d, days):
11811148
assert 1 <= d.__day <= 28 or -28 <= d.__day <= -1

0 commit comments

Comments
 (0)