- Feature Articles
- CodeSOD
- Error'd
-
Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Edit Admin
<question type="stupid">How . . . how does someone know about DateTime() but not .AddMonths() ?</question>
Edit Admin
{question type="stupid"}How . . . how does someone know about DateTime() but not .AddMonths() ?{/question}
Edit Admin
Magic strings are just as bad as magic numbers. Or worse.
Edit Admin
The one line we see is a terniary of the form
value = (condition) ? replacementValue : value
Which suggests there's a whole cascade of these statements one after the other, with the expectation that zero or one of the conditions evaluates as true, and if it's zero, then the original beginning value survives unscathed after n useless reassignments to itself.
IOW, they've reinvented the switch / case statement, but badly. And depending on how the various replacement values are computed, several weird things could occur if two or more of the conditions proved true and the second true case used the results of the first true case as input rather than the default value as input.
Just bad all around. As @dpm indirectly said, this is the work of somebody who knows the syntax of about half their language and a semi-random 1/10th of their language's + libraries complete OM / API.
Edit Admin
@dpm Your second post just calls out, screaming at the top of its lungs, for a "YMBNH" type of response...
Edit Admin
What I don't get is, how did they not detect this earlier?
Edit Admin
@tom103 : Easily explained. The users never filed a coherent bug report before.
Addendum 2025-10-16 09:55: Or this time, but they got lucky at last.
Edit Admin
Remy, I disagree with your rant against drop-down text descriptions. For example, if you were using an app would you want to figure out the date for the start of the quarter or just be able to pick from a drop-down "Start of Quarter"? I work in the financial industry and we have these all over the place - a most useful one is PBD (Prior "US" Business Day) which skips over bank holidays.
Admin
Because it is "AddMonths()" and they couldn't find the "SubtractMonths()" function
Edit Admin
My complaint was about passing string literals to the code, instead of like, an enum.
Admin
That's why I use Carbon in PHP.
Admin
...which means they had no idea how to populate a dropdown box properly.
Edit Admin
We don't know that they didn't use an enum for the dropdown box. We just know that by the time we got here they had a string.
Admin
Is there some reason for the DateTime constructor to not to use AddMonth logic in the month parameter, whether the value is out of bounds or not?
This is a serious question that I am asking on -3/16/2026.
Edit Admin
@Steve The Cynic: maybe dpm had this comment scheduled to be posted for "Same day same month same year". Remy would argue this should be labeled "now", but we here all know better ;)
Admin
As a long time PHP developer, I’ve seen this before back when it was the only way to do it. PHP 4 (and most of 5) is just a thin wrapper around C/C++ library function, so the only way to work with dates and time is a UNIX timestamp. The great tool was
strtotime
, which would take things like "Start of last month" as values. It would also consistently do the wrong thing. The documentation says that strtotime("February") will return a day in March if you run it on the 30th. It also did similar things when crossing year boundaries. While the DateTime class and friends fixed most of it, there were still weird ass problems well into PHP 7Edit Admin
Alternative option is to have last month implemented as "(Month - 1) % 12" (if it's 0-11) or "((Month - 1) % 12) + 1" (if it's 1-12)... modular arithmetic works backwards just fine and as expected - (-1 % 12) = 11.
Edit Admin
Unless you happen to be working with one of the many languages where -1 % 12 = -1.
Admin
My instinct would be to do that operation as "(Month + 11) % 12". Or "((Month + 10) % 12) + 1" if it's expected to be 1-12. That negates the entire question of what a negative number modulo something else would come out as.
But my first instinct would be to look for DateTime operations within the language. If you're not using C or similar 'ancient' languages, there's no excuse for not having them. (If you ARE using C or similar 'ancient' languages, and it's not an already existing codebase, I have to ask - why?)
Admin
Question: Is -3/16/2026 the Antiwednesday of Sixteenember next year, or is it Antimarch the 16th next year? Please reply before 2025.addYear().
Edit Admin
Well, the correct way to handle those business cases in legacy syntax (pre .net 10) looks like this:
So you can see it only works for local dates (extremely important, not using UTC is the trillion dollar mistake) and there is an issue with the term "same day" that needs to be addressed.
Addendum 2025-10-17 03:31: Welp, and there I mess up the first operation by using the wrong method :-)
Addendum 2025-10-17 03:33: 03:31? What is that Remy? Alien time? It's 07:33 :-)
Addendum 2025-10-17 03:38: And I forgot .Date for the SameDay operations. Ah well, should have written this properly with tests.
Admin
But of course this has problems when you do DATE(2025, (1 + 1), 29), which gives you the first of March. In Java the LocalDate.of(2025, 1, 29).plusMonths(1) gives you the 28th of February.
However, Excel is consistent: because the 29 is out of bounds it adds a day. So there is that.
Admin
Worse. You never have a 9 in the wrong case, or a non-breaking 2 instead of a normal 2.
Edit Admin
Fixed it up, so yeah, there's a lot that goes into local time nonsense. Best to avoid it, because business logic based on time zones will mess with you as soon as you have to deal with more than one. And I'm pretty sure I haven't even covered all of it, just the basics.
Admin
"The end users of Claus's application do a lot of work in January. It's the busiest time of the year for them."
I thought their busiest time of year was December?
Admin
Honestly I am not sure what that would accomplish in cases like this.
I mean, yes, it would help avoid the very niche problem of someone abusing the DateTime class in this way. But it would add both a big performance penalty to the constructor (not to be neglected when dealing with systems that generate a lot of these objects like messaging or logging systems) and more importantly lead to a constructor that behaves very strangely to the end user. All for the dubious benefit of "fixing" a bug that was introduced through misuse of the class to begin with.
I mean, imagine something like this: new DateTime(2024, -3, 12, 15, 73, 13). If the constructor was implemented as you say that would produce the date: 2023.09.12 16:13:13. Or maybe 2023.10.12 16:12:13, 2023.10.12 16:13:13 or 2023.09.12 16:12:13. It all depends on how you treat 0 as a value since right now DateTime considers it invalid.
But even ignoring that gotcha let me ask you. Do any of those really make more sense than "-3 is not a valid value for month"?