5 ms·
The problem is not in the `plus` method, as it's working as expected when the unit is in days. It's the `month` unit that is misleading, since `1 month` looks
by hcarvalhoalves 5y ago
The problem is not in the `plus` method, as it's working as expected when the unit is in days.
It's the `month` unit that is misleading, since `1 month` looks like a constant value but really isn't, as the behaviour depends on the other operand, breaking associativity – or any expectation on how addition between two constants work really.
It would be less confusing if the API removed `month` as a period, and as a programmer you would have to write:
periodLength = t.advanceMonths(1)
t' = t.plus(periodLength days)
This way you can only `plus` in constant units (days), and `advanceMonths` is free to follow any heuristic and return anything depending on the value of `t` without breaking the expectations of `plus`, or you can have any number of functions with different definitions for "advance N months".
- foobar1962 5y agoI was going to post exactly this: the problem is "month" which is not a fixed value. "Year" also has the same problem due to leap years. I suppose that leap seconds could also pose problems too. I've recommended that clients specify time periods in days or weeks and avoid "months" entirely (ie, 90 days or 26 weeks, but not 3 months) or to specify an end date explicitly.
- deathanatos 5y agoNone of day†‡, hour‡, or minute‡ are fixed duration, either, depending on use cases & circumstance. An absolute delta type is good to have, but it's also useful to have a "relative delta" type (how my language calls it). Each has their use cases. † ±1–2h on DST enter/exits ‡ ±1s during leap seconds
- tshaddox 5y agoAnd of course if day isn’t a fixed duration, then no intuitive definition of week would be a fixed duration either.
- euske 5y agoThis is just a hindsight, but I'd make two kinds of time period: "exact" period and "flexible" period. Define these as two different types, which can be converted to each other but only explicitly. Functions like plus() can take both types (via method overload) but the user must be aware that their behavior is different.
- deleted 5y ago[deleted]
- TeMPOraL 5y agoThe month itself is unnecessary complex because long ago, someone decided to break a perfectly good calendar. Ever wondered why the variable-length month is second in the year, instead of a last? English names of months offer a hint: "September", "October", "November", "December" - sound similar to "hept-", "oct-", "non-", "dec-", i.e. 7th, 8th, 9th and 10th. So as it turns out, February used to come last, as reason would demand, but then the calendar got rotated right by two months. If we imagine the calendar as it was, with February being the last, then at least the mapping between "day of year" and "month, day of that month" would be a function of just "day of year", instead of being a function of both "day of year" and "what year is it".
- goto11 5y agoDoesn't really change that adding n months to a date is an ambiguous operation. You would need to give all months the same length to avoid the ambiguity, but then months would not add up to a year, which has its own set of problems.
- goto11 5y agoAs far as I can tell, you agree with the articles main point. `plus` is a honest name for adding days to a date but dishonest when it comes to adding months. `advanceMonths` is an awkward but more honest name for adding months. An even more honest name would be `addMonthSameDayButCapIfShorter()` or something like that which reflect the gnarly behavior. A weird operation deserves a weird name. I don't like if `advanceMonths` returns an interval though, since this indicate that the interval is a meaningful unit separately from the initial date. It should return the new date, not an interval.
- stickfigure 5y agoAs others have pointed out, `plus` has odd behaviors for days, hours, and minutes too (DST, leap seconds). That's because dates are weird. Absolutely anyone who works with dates needs to understand this. There's no point in calling the method `plusWeird`, that's redundant. The good news is that most people actually have an intuitive understanding of dates (because we have spent our lifetimes looking at calendars) and when you are doing exotic date math ("move this to the same date next month") the default behavior of `plus` is what you want. I spent a lot of time working with Joda Time (and now java.time). I use date math functions on the regular, professionally. I found this API intuitive and ergonomic from the get-go, and well matched to the problem domain. What I see in this thread is a bunch of people with a relatively poor grasp of the problem domain trying to rethink the API.