-
Notifications
You must be signed in to change notification settings - Fork 1
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
Consider using different representation for CalendarDuration
#1
Comments
I think your proposal for I was recently made aware of https://github.com/matthiasbeyer/kairos which uses chaining to combine different durations. This way you can say "first add one month and then 5 seconds" or "first add 5 seconds and then two months" which resolves the "arbitraryness" of my approach. I will try this out in this chrono fork here https://github.com/kosta/chrono/tree/date-iterator but I'm really short on time at the moment (was sick and need to finish something for work) |
Sounds great! |
Note however that this still has the issue of whether to first add years, months or dates. Maybe CalendarDuration should instead be enum CalendarDuration {
Year(i32),
Month(i32),
Day(i32),
} So you can only add years plus months by ordering them via proper chaining. Also, one might want to specify behaviour or invalid dates, i.e. reject (return None), previous (return Feb 28th instead of Feb 31st) or next (return March 1st instead of Feb 31st), so this would become enum InvalidDateHandling {
Reject,
Previous,
Next,
}
enum CalendarDuration {
Year(i32, InvalidDateHandling),
Month(i32, InvalidDateHandling),
Day(i32),
} Does this make enough sense to try to implement it? |
Per the request in chronotope/chrono#184 I'm going to go ahead and open some code-review comments in here.
The first thing that a deeper reading of the code gives me is the shape of the
CalendarDuration
struct. It combines atime::Duration
and some calendar-centric items like months and years.What does it mean to add a duration that is
1 month and 5 seconds
? How do we do the bookkeeping for leap hours and leap seconds?Looking at other languages that have similar constructs:
java.time.Period
has just Year, Month, Dayboost.date_time.gregorian
is (seems to be) the same. The STL appears to only have a timespan-based duration. I have heard that there are plans for a revamped C++ datetime library, but I haven't ready much about it.timedelta
, which is not the same as what we're trying here. There is, instead, thepython-dateutil
package'srelativedelta
class, which is kind of a combination of what you've got here and the interfaces in the next section.Then we get into languages that have methods directly on
DateTime
types. I'm just going to talk aboutadd_months
, since it has the same problems asadd_years
and lets us ignore the difference betweenadd_seconds(86_400)
andadd_days(1)
.AddMonths
on theDateTime
type.So the takeaway from this is: most languages only provide seconds-based durations in the std (like rust) but when you start allowing calendar manipulation a clear distinction between temporal durations and calendar periods is important.
To that end, I think I'd rather that the shape of the CalendarDuration struct looked like:
With corresponding constructors. If users want something like Python's
relativedelta
API, then it's much more clear to do something like:Than something like:
When you start iterating over things like that, being able to separate out parts of the logic that depend on timezones and Leaps from parts that are purely calendar centric seems, to me, to be better.
What do you think?
The text was updated successfully, but these errors were encountered: