3 ms·
I'll never understand why they thought 0-based months made sense, but then used 1-based days and 1900-based years. Even if C did it. Almost feel like I can hear
by Clownshoesms 9y ago
I'll never understand why they thought 0-based months made sense, but then used 1-based days and 1900-based years. Even if C did it. Almost feel like I can hear the committee:
"Meh it's only a Date class, no one will really use it, will they? Billy already committed the code for 0-based months. Who here does not think of January as month zero?"
feet nervously scuffing carpet
"Right, settled! Moving on, company picnic is on the 1st of 0 next year (96)".
- jcranmer 9y agoThe java.util.Date API is pretty clearly modeled off of POSIX time, and therefore retains compatibility with POSIX's wrong decisions. I suspect that POSIX used 0-based months so they could index into some const char *monthNames[]; variable; since years and days are shown directly, there's no need to force them to be 0-based (not that day-of-week and day-of-year are 0-based as well).
- Clownshoesms 9y agoI didn't realize that came from POSIX or was an attempt at complying with it. Yes the array indice makes sense (although exposing that externally and not just adjusting the value internally seems like a poor decision). Not sure why Java felt the need to carry that behaviour across, I can't recall anyone clammering for POSIX compliant date handling.
- pluma 9y agoThe funny part is that JavaScript copied this behaviour from Java for compatibility (in fact most of JavaScript's Date's behaviour is a direct copy of Java's). I didn't know that this is one case where Java copied from C, which means JS copied it from Java and Java copied it from C (which itself seems to have inherited it via POSIX), all in the name of API compatibility but confusing the majority of programmers in each language every time.
- bluetech 9y agoThere is this: https://github.com/maggiepint/proposal-temporal https://github.com/maggiepint/proposal-temporal A proposal to copy java.time to javascript. Hopefully this will happen eventually!
- avar 9y ago> I'll never understand why they thought 0-based > months made sense, but then used 1-based days > and 1900-based years. Even if C did it[...] Java, Perl etc. all copied this pattern from localtime() in C. In all of these languages it's idiomatic to write something like: printf("%s %d, %d\n", mnames[mon], mday, year); To print out e.g. "January 6, 78". The reason month days aren't zero based is obvious, usually when you use them you aren't going to have go through a lookup table, whereas nobody calls January "0" or "1", so you'll always need a lookup table. Indexing months by 1 would mean declaring the "mnames" array would be the un-idoimatic: char *mname[] = { NULL, "Jan", ... }; Instead of: char *mname[] = { "Jan", ... }; Or you'd need to use the latter form and do lookups by mnames[mon - 1] instead of mnames[mon]. The reason you have to add 1900 to the year is that when C was made it was standard for software to use two-digit years, and if you told some of C's designers back in the 70s that we'd still be using & discussing these APIs in 2017 they'd probably have laughed at you. Of course sometimes you need to use month indexes themselves, e.g. if you wanted to print out 1978-01-06 in a log file: printf("%d-%d-%d...\n", year + 1900, mon + 1, mday, ...); But such are the trade-offs of low-level API design. I guess C's designers took the inherent idiomaticness of zero-based indexes & expectation that the common case would to print out month names over such use-cases.
- Sharlin 9y ago> whereas nobody calls January "0" or "1" Eh, in many locales it's idiomatic to refer to months by number, not by name, especially in the "short form" of a date. So you end up having to add one to the month number. But of course when they made C they didn't think about internationalization either...
- jdmichal 9y ago> Or you'd need to use the latter form and do lookups by mnames[mon - 1] instead of mnames[mon]. All of which should be hidden behind your API anyway. It was a terrible choice, because it forces the client to deal with weird things just so that you can squeeze a single decrement out of your code.