Skip to content

Fix dlang#10783: Datetime: Make adding a Duration to Date commutative #10818

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Inkrementator
Copy link
Contributor

The types Date, DateTime and TimeOfDay already implement adding and subtracting a Duration to them.

This makes the addition of a Duration commutative via implementing opBinaryRight.

I chose opBinaryRight over Duration.opBinary, since Duration is in druntime, which shouldn't depend on phobos.

Only addition is implemented here. DateTime and Date already principally support negative Dates, i.e.

Date(0, 1, 1) - days(7) // 0001-Dec-25

works and can be interpreted as Before Christ (BC) dates. On the other hand opUnary isn't implemented (yet), which seems like a precondition for making subtraction commutative in a way that makes sense via the transformation:

days(7) - Date(0,1,1)
=> -Date(0,1,1) + days(7)

and even then the semantics of subtracting a Date from a Duration is debatable.

The types Date, DateTime and TimeOfDay already implement adding and
subtracting a Duration to them.

This makes the addition of a Duration commutative via implementing
opBinaryRight.

I chose opBinaryRight over Duration.opBinary, since Duration is in
druntime, which shouldn't depend on phobos.

Only addition is implemented here. DateTime and Date already
principally support negative Dates, i.e.

	Date(0, 1, 1) - days(7) // 0001-Dec-25

works and can be interpreted as Before Christ (BC) dates. On the other
hand opUnary isn't implemented (yet), which seems like a precondition
for making subtraction commutative in a way that makes sense via the
transformation:

	days(7) - Date(0,1,1)
	=> -Date(0,1,1) + days(7)

and even then the semantics of subtracting a Date from a Duration is
debatable.
@Inkrementator Inkrementator requested a review from jmdavis as a code owner July 11, 2025 19:04
@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @Inkrementator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + phobos#10818"

@Inkrementator
Copy link
Contributor Author

Github hyperlink: #10783

@jmdavis
Copy link
Member

jmdavis commented Jul 13, 2025

Personally, I don't think that it makes any sense for adding a Duration to a Date to be commutative. Conceptually, the Duration is being added to the Date. The Date is not being added to the Duration. So, I'm against this change.

But even if we decide that we want this change, it's going to need to be made to SysTime as well for consistency.

@Inkrementator
Copy link
Contributor Author

Conceptually, the Duration is being added to the Date. The Date is not being added to the Duration.

I agree. Otoh, the result of adding a Date to a Duration is obvious and the complexity overhead of supporting it is minimal.

The upsides are similarly limited. Not running into a (quick to fix) error when you accidentally mix up the order of Date and Duration is nice to have. Someone new to the language might not even instantly understand the compiler error:

none of the overloads of template `core.time.Duration.opBinary` are callable using argument types `!("+")(DateTime)`

Having quickly written code "just work" is valuable for the use case of using D instead of a scripting language.

@jmdavis
Copy link
Member

jmdavis commented Jul 13, 2025

I completely disagree with making duration + date work, because it makes no sense conceptually, and the programmer should know what they're adding together, making it easy to figure out what they did wrong if they get the order wrong for some reason. So, I don't see any problem with it being an error. And I have never seen this issue come up in the 15 years or so that std.datetime has existed. So, I don't buy that this is a problem that much of anyone has been running into or that it's something that needs to be solved.

Having quickly written code "just work" is valuable for the use case of using D instead of a scripting language.

This feels to me like an arguing that a misspelling for a function should be added as an alias just because someone might misspell the function when writing code quickly. Just because code is in a script doesn't make it special, and it's plenty fast to write the code correctly in the first place.

@Herringway
Copy link
Contributor

I completely disagree with making duration + date work, because it makes no sense conceptually, and the programmer should know what they're adding together, making it easy to figure out what they did wrong if they get the order wrong for some reason. So, I don't see any problem with it being an error. And I have never seen this issue come up in the 15 years or so that std.datetime has existed. So, I don't buy that this is a problem that much of anyone has been running into or that it's something that needs to be solved.

It is an inconsistency without purpose. That should not be tolerated.

Having quickly written code "just work" is valuable for the use case of using D instead of a scripting language.

This feels to me like an arguing that a misspelling for a function should be added as an alias just because someone might misspell the function when writing code quickly. Just because code is in a script doesn't make it special, and it's plenty fast to write the code correctly in the first place.

As a Canadian occasionally writing colour-related code, I've dealt with this issue a few times...

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.

4 participants