There are a number of reasons why it might make sense to separate the absolute and relative components of relativedelta.relativedelta:
- People are often confused by the fact that the arguments have such similar names -
month vs. months - easy to miss in code review, etc.
- The absolute arguments make it way less meaningful to compare these things, and the differences around which components change if you add/subtract things are not intuitive.
- There is a meaningful abstraction for the absolute components - a "partial date" - e.g. "month=2, day=1".
I suggest an implementation where all the absolute components are refactored out of relativedelta and into a partialdatetime object - which itself would be composed of a partialdate and partialtime object. These would have the following properties:
- They can be fully empty, and empty
partial* objects are falsy.
- They can be used to update existing dates - the interface for this is unclear, but we'll want a simple method for using them to update `datetime objects, some options:
- Implement them as a subclass of something that can be expanded with double-stars (
datetime.replace(**p_dt))
- A method that returns a
dict (datetime.replace(**p_dt.asdict()))
- A method on
partialdate that updates the datetime (partialdate.update(dt)) (not great)
- Override
__add__ to mimic the existing relativedelta interface with datetime (also not great)
The following are still open questions:
- Mutability - should they be immutable like
datetime, or mutable? I'm leaning towards immutable.
- Binary operations - how should they be defined? What is
partialdate(year=2017, month=2) < partialdate(year=2017, day=14)? How about partialdate(year=2017, month=2) - partialdate(year=2016)?
I'd say that they should be added as a keyword argument and main implementation for relativedelta relatively soon, and then the absolute arguments should be deprecated in the following release. Ideally we'd factor out the non-absolute components into a separate object at the same time, but I think the correct name for that object is relativedelta, so I'm not sure what we would want to call the super-object in that case.
There are a number of reasons why it might make sense to separate the absolute and relative components of
relativedelta.relativedelta:monthvs.months- easy to miss in code review, etc.I suggest an implementation where all the absolute components are refactored out of
relativedeltaand into apartialdatetimeobject - which itself would be composed of apartialdateandpartialtimeobject. These would have the following properties:partial*objects are falsy.datetime.replace(**p_dt))dict(datetime.replace(**p_dt.asdict()))partialdatethat updates thedatetime(partialdate.update(dt)) (not great)__add__to mimic the existingrelativedeltainterface withdatetime(also not great)The following are still open questions:
datetime, or mutable? I'm leaning towards immutable.partialdate(year=2017, month=2) < partialdate(year=2017, day=14)? How aboutpartialdate(year=2017, month=2) - partialdate(year=2016)?I'd say that they should be added as a keyword argument and main implementation for
relativedeltarelatively soon, and then the absolute arguments should be deprecated in the following release. Ideally we'd factor out the non-absolute components into a separate object at the same time, but I think the correct name for that object isrelativedelta, so I'm not sure what we would want to call the super-object in that case.