- Feature Articles
- CodeSOD
-
Error'd
- Most Recent Articles
- Mike's Job Search Job
- Teamwork
- Cuts Like a Knife
- Charge Me
- Que Sera, Sera
- Hot Dog
- Sentinel Headline
- Mais Que Nada
-
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
Admin
On some level, they got lucky to catch this bug, because it roughly occurs only on one day out of four years. On the other hand, I suppose they always run their little report on the last day of the month, so it was bound to happen?!
Admin
Crystal Reports, and a production database we couldn't touch with different settings than the test/development instance. What an absolute waste of time that was.
Admin
To be fair, though,
This is a bug that is only going to show up for one day every four years.
That is pretty good work by TDWTF standards.
Admin
Years ago I had to work with Crystal Reports, or to be more precise, a Delphi component wrapper for Crystal Reports. I never found out if the issue was with CR itself or the wrapper, but the damn thing leaked memory like there was no tomorrow.
Now what I had to create was an app that run several reports in succession, so I ended up creating a list of reports, copy that file, and feed it into the app that ran 10 reports (and removed them from that copied file), launch another instance of the app, close the current one, and keep going until all reports had been run.
Was that a terrible, filthy hack? Yes. Did it work? Also yes. Was I happy about any of it? Not at all. If it hadn't been for Clarion I'd call CR the most awful software I ever had the misfortune of having to work with.
Admin
The logic for extracting parts of the date doesn't even make sense. It's obvious that the date must be formatted like "yyyy/MM/dd hh:mm:ss. In that scenario, the first four characters are the year. Sure. Then you start at index 5 and take two characters for the month. Ok, sure. Then you start at index seven, which is the second "/", and take two characters for the day. That gives you "/x" where x is the first digit of the day. Hour starts on the second character of day. Minute starts on the first character of hour, so minute is populated with hour instead. And second starts on the first ":" between hour and minute, so it gives you ":x" where x is the first character of the minute.
Admin
Things like Crystal Reports - and the myriad of low-code / no-code 'solutions' - are actually alright for doing very simple things. The problem is that businesses see the simple thing and decide that "it'd be good if it could also do...' too.
Which makes it that bit more complicated and beyond the real scope of what CR et al. can do. That in turn means that weird hacks come into play.
Repeat this a few times and you end up with some obscene, fragile behemoth that no-one really understands (because Jeff who originally wrote it left years ago) and that no-one really wants to go near - but which has become absolutely business critical.
Then the sunk cost fallacy comes into play and rather than just bite the bullet and rewrite it in something more appropriate, more and more bodges and hacks are applied - usually under duress by the poor soul charged with making the changes.
It often takes a change in management - or a catastrophic failure - to force the retirement of said solution. A penny not spent today means a dollar spent tomorrow.
Admin
I assume the date is formatted "yyyyMMddhhmmss" and the Mid function is called like "starting with the 5th character take 2 characters", because 0-indexing is too complicated for end-users
Admin
Date handling code is difficult to write all 32 days of the month.
Admin
Sounds more like the Delphi wrapper was not disposing those COM objects correctly. We had to use CR in production as well, I wrote the C# interop wrapper back then because there wasn't anything available and my service produced hundreds of reports per day and didn't need to be restarted ever. Our server maintenance schedule was back then monthly, so any memory leak would have been super obvious, even a small one. Then again, who knows, CR was a very inconsistent black box (especially the performance was all over the place), so maybe I just got super lucky back then.
Admin
Leap years and DST... always lurking with trouble. We can't do much about leap years, but can we at least eliminate DST in our lifetimes? Sheesh.
Admin
Ok, that makes sense. There doesn't seem to be any way for it to work if Mid takes starting index and length, but it works if it's starting position.
Admin
It has been tried several times before, and every time it has, people start complaining about it getting dark too early or some other issue.
It's become one of those "damned if we do, damned if we don't" situations.
Admin
Those string functions are clearly borrowed from Basic, though without the final '$'. Basic had Left$(...), Mid$(...) and Right$(...) (well, more usually, LEFT$(...), MID$(...) and RIGHT$(...)) and strings indexes were 1-based.
Admin
Another one of those tools that LET (not lets). The relative clause describes the tools, not the one.
Admin
When I saw the error message I just knew it would be a leap year issue.
And time zones!
Admin
Really it's leap years, DST, and timezones.
Timezones are the WTF that everybody seems to always forget, even in larger international corps, because most people only deal with their own timezone daily, and even those who try make invalid assumptions. There's more snakes in there than in an Indiana Jones pit.
Admin
I still have to work with Crystal, for my sins. We have so many reports written using Crystal that it would take our entire team years to switch to a different product. The problem is that it actually produces very smart PDF reports if you need to reproduce complicated designs, and many reporting products aren't designed to do that. When using Crystal, I am always reminded of this quote from the Hitch-Hiker's Guide to the Galaxy: “It is very easy to be blinded to the essential uselessness of [their products] by the sense of achievement you get from getting them to work at all. In other words—and this is the rock solid principle on which the whole of the Corporation’s success is founded—their fundamental design flaws are completely hidden by their superficial design flaws.”
Admin
Wow! I've always thought my adventures in Reporting Services were bad. But I am to understand they took the whole... sales ledger (?) into CR and then selected the relevant entries? What a mess!
But then again, I bet the alternative would have been a stored procedure doing string munging.
Also, I sincerely hope this report failed all of February on a leap year, not just if you run it ON the leap day. Surely the ReportToDate value isn't current date, and you have to be there and run the report regardless of what day of the week it is... though that wouldn't surprise me either...
Unless, of course, you feed it the 28th of February and "misplace" the 29th... also something I could see happening with this mess... or well, it wouldn't be lost... just not included in February... Or, depending on the logic of the selection, the 29th would be included when it shouldn't... Yay!
Addendum 2025-05-10 23:24: P.s. Also, hours, minutes, seconds?!? Is this a stock ticker? :O D.s.
Admin
I refuse to support CR, and I don't give 2 craps if database schema changes I make break the CR stuff :)
I live in a database world where SQL is an afterthought for it, and despite setting the format of a character field to X(30) -- Which sets the SQL width to 60 chars, I can shove over 200 chars into that field if I want.
All that it means is that the old character client can't display all of them, and anything that interacts with the database via SQL (Database at best talks SQL92), chokes to death on those fields :D
Thankfully, CR and an Access Database are the only 2 things that communicate to the main database via ODBC.
Admin
Yes, sounds like 1 in 1461 chance, but if they are only running the report at the end of the month, it's really 1 in 48 chance. 100% chance every 48 months.