News for hackers. Stuff that matters.
Re:Good Design is Imperfect Design, Part 1: Honest Names by mjevans on Wednesday August 04, 2021 @02:30PM (#28064487)
You seem to be stuck on: 'what is the value of 1 month' and thinking in terms of days, because that appears to be the precision of the left value.

Programmers exist in a world where things such as leap seconds matter. Normally if you have a timestamp that is just before a leap second, then add exactly a day's worth of seconds, you'd slide back a little in time. This might matter in another context, such as defining the limits of neighboring ranges properly. Also, who's to say the underlying precision is a second?

The intent of the library in question is to behave the way most people would. With imperfect buckets and idealized answers; yet also precision where someone makes the attempt to be specific.

None of the examples in the article use a more vague syntax, such as "0 days before the end of the month". They start with what a human might, a rounded but full date; then apply an interval. So a more clear contrived example might be.

  Jan 31 .plus(1 months) => Feb 28
  Jan 31 .plus(2 months) => Mar 31
  Jan 31 .plus(3 months) => Apr 30
  Jan 31 .plus(4 months) => May 31
  Jan 1 .plus(1 months) => Feb 1
  Jan 1 .plus(2 months) => Mar 1
  Jan 1 .plus(3 months) => Apr 1
  Jan 1 .plus(4 months) => May 1
Note how in the second half there are still variably sized months, but the result is what a human would want.
Re:Good Design is Imperfect Design, Part 1: Honest Names by tmp538394722 on Wednesday August 04, 2021 @02:52PM (#28064734)
You’ve ignored your critique and answered only the more obvious anecdotes.

So I’ll repeat:

What’s Feb 28th + 1 month?

Does the human expect the last day of March? Or the 28th day of March?

The API doesn’t make that clear - I think you could reasonably argue for either.

Re:Good Design is Imperfect Design, Part 1: Honest Names by jimminy on Wednesday August 04, 2021 @03:31PM (#28065190)
If you're adding 1 month, you're working on the month's location, e.g. 2021 - (02) - 28.

When you increment the month, the result would be 2021-03-28.

The only time you'd modify the day, is if the day became invalid due to an overflow, during that increment. If, when, you overflow the days you'd set the value of days to the maximum in that month.

If I tell someone, I'll get to that in a month, they expect by this day in the next month, the next calendar page, not 30/31 days.

Re:Good Design is Imperfect Design, Part 1: Honest Names by depaya on Wednesday August 04, 2021 @06:26PM (#28067253)
You're setting the same trap as those viral math problems people share on Facebook:

6÷2(1+2) = ?

We could argue about what the _right_ answer is to that equation, but I call it a trap because it's intentionally confusing and devoid of any context (or the ability to ask a follow up question). There isn't really a situation where you would see that equation and not know the intended way to interpret it... just like your question.

There are a couple of ways that context _could_ be provided though:

I'm writing an automated task that should run once per month, I don't necessarily care what day of the month it runs though since it just cleans up some temp files. If today happens to be Feb 28th, and I say run today, then every month after, I would expect it to run Feb 28th, March 28th, April 28th...

I'm writing an 'end of month' task that needs to run at the end of every month for some bookkeeping reason. If today happens to be Feb 28th, and I say run today, then every month after, I would expect it to run Feb 28th, March 31th, April 30th...

In both of these situations I would program accordingly. Computers don't understand context, that's the job of the human programming it.

Re:Good Design is Imperfect Design, Part 1: Honest Names by ummonk on Wednesday August 04, 2021 @09:19PM (#28068583)
The human expects March 28th. Ask any normal person and they’ll answer March 28th.
Re:Good Design is Imperfect Design, Part 1: Honest Names by brianpan on Wednesday August 04, 2021 @03:03PM (#28064861)
The article is about naming the method. The fact that dates are messy means a clean API is difficult/impossible.

I think plus() is a name that is good enough. I can't think of a better name that will help the user understand what will happen in the 2/28 + 1 month case. That's asking too much of a method name. That's what docs are for.

Re:Good Design is Imperfect Design, Part 1: Honest Names by opheliate on Wednesday August 04, 2021 @03:08PM (#28064932)
Perhaps .dateAfter(1 month) would be more appropriate? I sympathise with the author in finding the violation of associativity of “plus” a bit jarring.
Re:Good Design is Imperfect Design, Part 1: Honest Names by mcphage on Wednesday August 04, 2021 @04:29PM (#28065899)
I think that's the easier case—most people would expect Feb 28th + 1 month = Mar 28th. The tricker one is Jan 31 + 1 month, because there is no Feb 31st. I don't think there is a "correct" answer to that.
Re:Good Design is Imperfect Design, Part 1: Honest Names by FabHK on Wednesday August 04, 2021 @06:13PM (#28067111)
If I pay you Jan 31, Feb 28, March 31, April 30, etc., don't I pay you monthly? Shouldn't I be able to express this as a repeated addition of a month?

At any rate, these problems have been solved in finance, with proper date and schedule libraries.

Re:Good Design is Imperfect Design, Part 1: Honest Names by mjevans on Wednesday August 04, 2021 @06:56PM (#28067519)
No, you should be able to express it the way I mentioned in other examples: Base .plus( N months ) where N is whichever month after the reference you want.

.plus .plus .plus isn't correct because "x months" doesn't have a fixed size. You are NOT saying Base .plus(30 days), NOR are you saying Base .plus(4 weeks) ((which BTW, I'd expect to stay on the same weekday)). You're incrementing by an unstable value.

Re:Good Design is Imperfect Design, Part 1: Honest Names by saurik on Wednesday August 04, 2021 @09:27PM (#28068655)
This doesn't work either as it wouldn't work correctly if started in a month with less than 31 days. To represent "the last day of the month" you really need to be subtracting one day from the first day of the next month, full stop: any solution working off of these weird rounding rules is going to be unreliable.
Re:Good Design is Imperfect Design, Part 1: Honest Names by mcphage on Wednesday August 04, 2021 @08:02PM (#28068035)
> Shouldn't I be able to express this as a repeated addition of a month?

I don’t think so, no—more likely, it should be Pattern(Month)… like how would you express “second Tuesday” as a series of additions?

Re:Good Design is Imperfect Design, Part 1: Honest Names by saurik on Wednesday August 04, 2021 @09:26PM (#28068645)
To express this in a sane way you want to express "the last day of the month". You can't claim it is "just keep adding to the hire date one month times the current month minus the hire month" as if I hire you in February that won't work. You really need to be calculating "take the current time, replace the day with 1, add one month, subtract one day" to get the next pay date.
Re:Good Design is Imperfect Design, Part 1: Honest Names by mjevans on Wednesday August 04, 2021 @04:02PM (#28065581)
I did cover that:

""" None of the examples in the article use a more vague syntax, such as "0 days before the end of the month". """

As another reply points out, it's incrementing the Month set of buckets. I'll also extend with other results I expect:

  2020-12-31 .plus(1 months) => 2021-01-31
  2020-12-31 .plus(2 months) => 2021-02-28
  2020-12-31 .plus(3 months) => 2021-03-31
  2020-12-31 .plus(4 months) => 2021-04-30
A normal human has several options, and truncating to stay within the month makes the most sense to the most people most of the time. It's perfectly reasonable to take that step when resolving the indicated date to a representable value.

I'll go further: JodaTime probably isn't focused on Precision Date Calculations; it behaves very much the way I expect someone working with forms and fields, general CRUD enterprisy software stuff, would want auto-filled dates to work.

Re:Good Design is Imperfect Design, Part 1: Honest Names by kaishiro on Wednesday August 04, 2021 @05:27PM (#28066565)
Maybe I'm just being thick (it's usually the case), but for the life of me I still don't know what your answer to the parent's question is, and I can't tell how your quoted part is supposed to answer it.
Re:Good Design is Imperfect Design, Part 1: Honest Names by mjevans on Wednesday August 04, 2021 @06:54PM (#28067492)
My 2 higher levels post post included an alternate phrasing of the test case they specified:

""" None of the examples in the article use a more vague syntax, such as "0 days before the end of the month". """

---

They asked:

""" What’s Feb 28th + 1 month?

Does the human expect the last day of March? Or the 28th day of March? """

---

It's implicit, the human only expects the month to change, because the input isn't a descriptive phrase "the end of the month" adjusted or not, it's a literal date. That's why my other test cases show the same behavior for the end of the month.

Re:Good Design is Imperfect Design, Part 1: Honest Names by prpl on Wednesday August 04, 2021 @03:40PM (#28065288)
It should be the 28th and there should be a ceiling method.