Skip to content

Commit e2ddcce

Browse files
authored
Improve performance of from_ordinal of temporal types. (#1047)
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 85404f3 commit e2ddcce

File tree

1 file changed

+7
-40
lines changed

1 file changed

+7
-40
lines changed

neo4j/time/__init__.py

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -900,35 +900,10 @@ def from_ordinal(cls, ordinal):
900900
"""
901901
if ordinal == 0:
902902
return ZeroDate
903-
if ordinal >= 736695:
904-
year = 2018 # Project release year
905-
month = 1
906-
day = int(ordinal - 736694)
907-
elif ordinal >= 719163:
908-
year = 1970 # Unix epoch
909-
month = 1
910-
day = int(ordinal - 719162)
911-
else:
912-
year = 1
913-
month = 1
914-
day = int(ordinal)
915-
if day < 1 or day > 3652059:
916-
# Note: this requires a maximum of 22 bits for storage
917-
# Could be transferred in 3 bytes.
918-
raise ValueError("Ordinal out of range (1..3652059)")
919-
if year < MIN_YEAR or year > MAX_YEAR:
920-
raise ValueError("Year out of range (%d..%d)" % (MIN_YEAR, MAX_YEAR))
921-
days_in_year = DAYS_IN_YEAR[year]
922-
while day > days_in_year:
923-
day -= days_in_year
924-
year += 1
925-
days_in_year = DAYS_IN_YEAR[year]
926-
days_in_month = DAYS_IN_MONTH[(year, month)]
927-
while day > days_in_month:
928-
day -= days_in_month
929-
month += 1
930-
days_in_month = DAYS_IN_MONTH[(year, month)]
931-
year, month, day = _normalize_day(year, month, day)
903+
elif ordinal < 0 or ordinal > 3652059:
904+
raise ValueError("Ordinal out of range (0..3652059)")
905+
d = datetime.fromordinal(ordinal)
906+
year, month, day = _normalize_day(d.year, d.month, d.day)
932907
return cls.__new(ordinal, year, month, day)
933908

934909
@classmethod
@@ -1218,17 +1193,9 @@ def __add__(self, other):
12181193
:raises ValueError: if the added duration has a time component.
12191194
"""
12201195
def add_months(d, months):
1221-
years, months = symmetric_divmod(months, 12)
1222-
year = d.__year + years
1223-
month = d.__month + months
1224-
while month > 12:
1225-
year += 1
1226-
month -= 12
1227-
while month < 1:
1228-
year -= 1
1229-
month += 12
1230-
d.__year = year
1231-
d.__month = month
1196+
overflow_years, month = divmod(months + d.__month - 1, 12)
1197+
d.__year += overflow_years
1198+
d.__month = month + 1
12321199

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

0 commit comments

Comments
 (0)