Skip to content

make DurationField store milliseconds instead of microseconds #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2024

Conversation

timgraham
Copy link
Collaborator

MongoDB's arithmetic operators like $add treat numbers are milliseconds.

if value is not None:
# Multiplying value converts milliseconds stored in the database
# to microseconds expected by timedelta.
value = datetime.timedelta(0, 0, value * 1000)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i am not mistaken, timedelta has the following parameters:
class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
Maybe we don't need the scalation if we just pass the valle to microseconds.

"""DurationField stores milliseconds rather than microseconds."""
value = _get_db_prep_value(self, value, connection, prepared)
if connection.vendor == "mongodb" and value is not None:
value = int(Decimal(value) / 1000)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Decimal? Can't it be: int(value) // 1000 ?

@@ -70,6 +70,9 @@ def value(self, compiler, connection): # noqa: ARG001
elif isinstance(value, datetime.date):
# Turn dates into datetimes since BSON doesn't support dates.
value = datetime.datetime.combine(value, datetime.datetime.min.time())
elif isinstance(value, datetime.timedelta):
# DurationField store milliseconds rather than microseconds.
value = value.total_seconds() * 1000
return {"$literal": value}
Copy link
Collaborator

@WaVEV WaVEV Jun 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I am wondering if (value / timedelta(milliseconds=1)).total_seconds() works?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, except that timedelta / timedelta gives a float, so no need for total_seconds(). Do you see an advantage to that version?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on no need of total_second I misunderstood the docs. https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds
But it recommended, by the docs, to use the division by time delta. I see no advantages, only the docs

@timgraham timgraham force-pushed the durationfield-store-millisecond branch 2 times, most recently from 3d97680 to 03b5e0c Compare July 1, 2024 14:36
Copy link
Collaborator

@WaVEV WaVEV left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@timgraham timgraham force-pushed the durationfield-store-millisecond branch from 03b5e0c to 2c87452 Compare July 1, 2024 21:22
MongoDB's arithmetic operators like $add treat numbers are milliseconds.
@timgraham timgraham force-pushed the durationfield-store-millisecond branch from 2c87452 to c769dcc Compare July 1, 2024 21:36
@timgraham timgraham merged commit c769dcc into mongodb:main Jul 1, 2024
3 checks passed
@timgraham timgraham deleted the durationfield-store-millisecond branch July 1, 2024 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants