Hacker News new | ask | show | jobs
by mattmalin 4033 days ago
I also imagined floating point arithmetic problems when seeing the title. What is really happening here is that a, b and c may themselves have different values depending on the operation - as adding a month here isn't a fixed number of days as month lengths differ.

The article states it perfectly at the end though: "When doing math that deals with time, specifically different units of time, it can lead to unexpected results if you are not careful with the ordering". I think this can generally be extended to "when doing any math that deals with time, it can lead to unexpected results if you are not careful with everything"!

4 comments

> "When doing math that deals with time, specifically different units of time, it can lead to unexpected results if you are not careful with the ordering"

Not arguing with you, but with the poster: I think that a deeper lesson might be the important realisation that, unlike 'day' or 'hour', 'month' is not a unit of time! (At least, not any more than 'moment' is. (I know, I know, https://en.wikipedia.org/wiki/Moment_(time), but you know what I mean.))

> unlike 'day' or 'hour', 'month' is not a unit of time!

Not a 'fixed unit' of time. Where I define 'fixed' as being always of the same size (like gram or meter).

My next thought is that day is also not fixed in case of daylight saving and leap seconds. A day has many definitions: astronomical, 24 hours, calendar, etc.

Maybe we can also see this problem with 'hour'; but in that case it would be more contrived.

Bottom line: programming time is hard, be aware of that.

See this post for some common pitfalls:

http://infiniteundo.com/post/25326999628/falsehoods-programm...

> Not a 'fixed unit' of time. Where I define 'fixed' as being always of the same size (like gram or meter).

I would regard that as part of what 'unit' means (https://en.wikipedia.org/wiki/Units_of_measurement), though I'm not sure that there's any universal agreement.

I think that it's fair to say that even, or perhaps especially, the most obvious concepts, when sufficiently well understood, exhibit subtleties. (I always tell students in my mathematics classes that the correct answer to every question is "it depends", and, though it's somewhat facetious, I honestly can't think of a mathematical statement so basic and obvious that a sufficiently sophisticated mathematician couldn't correctly raise this objection.)

With that said, while I agree that there may be different colloquial definitions of 'day' and, as you mention, of 'hour', and even of 'second' (https://en.wikipedia.org/wiki/Second#Other_current_definitio...), they also have unambiguous scientific definitions that can be pinned down by sufficiently precise reference; whereas 'month' simply does not.

EDIT: I should clarify that I'm not attempting by any of this to say that programming with times isn't hard—it absolutely is. I just think that a large part of it can be traced to confusion about what is not a unit (which, as observed by cies above (https://news.ycombinator.com/item?id=9665366) and DannoHung below (https://news.ycombinator.com/item?id=9665472), can include such seemingly innocuous concepts as 'day'), and that it might be profitable explicitly to state this unifying idea as one way to guide attempts to program successfully with time.

As long as we're posting wikpedia links: http://en.wikipedia.org/wiki/Leap_second

I wouldn't trust any time unit larger than seconds if I was concerned about my units staying consistent. Hopefully time-keeping bodies don't decide we need leap-millis at some point.

Which is only to say that this is a problem that can't be solved simply by discarding some concepts that you find problematic. There's a lot of shit about timekeeping that's problematic. I'd advise tossing all the problematic shit when trying to figure out some internal representation for the underlying time that more or less always makes sense and then building out more human-usable representations with the uglyness on top of it.

> Which is only to say that this is a problem that can't be solved simply by discarding some concepts that you find problematic.

> I'd advise tossing all the problematic shit when trying to figure out some internal representation for the underlying time that more or less always makes sense and then building out more human-usable representations with the uglyness on top of it.

I don't mean to be snarky, but these two sentences seem contradictory—you say that the problem can't be solved by discarding problematic concepts, then advise to discard problematic concepts. Are you making the point that, even if internally we work with an un-problematic representation of time (if such a thing exists!), at some point we have to convert to and fro? Certainly I agree with that. Though I seem to have said it badly, that's really what I meant to say above: trying to work directly with months (and, perhaps less dramatically, with days), which are not units of time, allows the problematic real-world notion of time to contaminate what should be the clean internal representation of it.

I guess? I'm saying that you can't realistically avoid working with the problematic units. Like, if you want to have a monthly payment system, at some point, you have to bake in the human concept of months into your system, warts and all.
Or more accurately, "Doing math that deals with different units of time will inevitably lead to unexpected results."

If you gather 6 different company executives and business requirement authors and ask them all to explain what it means to be "one month and 5 days later" than a given date, I guarantee you will get at least 3 or 4 different answers. No matter WHAT your code implements, it will be unexpected to some users.

As a developer, when I encounter a requirement like this one I feel it is my duty to push back on the requirement. I won't ACCEPT a requirement like "the grace period is a month and five days", and will instead (try to) force those writing the requirements to specify something clear like "the grace period is 35 days" or "the grace period is until 5 days after the same same date in the following month" (still somewhat misleading).

I have been working in software development within big business (banks, mostly) for quite some time now, and I frequently observe that developers -- probably because of the nature of their job -- tend to be good at thinking of something clearly and precisely, while those writing requirements tend to be fuzzy on the specifics but better able to understand the overall picture. Working at the interface between the two, my job is often to get each side to step up to the level of the other.

The same approach is in legal issues. Words "a month and a five days" shouldn't ever get past a lawyer, you'd get "35 calendar days" or more likely something like "25 business days as defined by XXX; if the notice is submitted past 18:00 then it's treated as if submitted on the next business day"
> What is really happening here is that a, b and c may themselves have different values depending on the operation - as adding a month here isn't a fixed number of days as month lengths differ.

spot on; very much a human mistake, a false assumption of how things work.

> The article states it perfectly at the end though: "When doing math that deals with time, specifically different units of time, it can lead to unexpected results if you are not careful with the ordering". I think this can generally be extended to "when doing any math that deals with time, it can lead to unexpected results if you are not careful with everything"!

Another idea: don't dress up things that don't have anything to do with conventional math as conventional math. Using operands who's value depends on the value of the expression evaluation up to this point (I'm guessing left to right) is an aberration.