Article 556KE CodeSOD: The Data Class

CodeSOD: The Data Class

by
Remy Porter
from The Daily WTF on (#556KE)

There has been a glut of date-related code in the inbox lately, so it's always a treat where TRWTF isn't how they fail to handle dates, and instead, something else. For example, imagine you're browsing a PHP codebase and see something like:

$fmtedDate = data::now();

You'd instantly know that something was up, just by seeing a class named data. That's what got Vania's attention. She dug in, and found a few things.

First, clearly, data is a terrible name for a class. It'd be a terrible name if it was a data access layer, but it has a method now, which tells us that it's not just handling data.

But it's not handling data at all. data is more precisely a utility class- the dumping ground for methods that the developer couldn't come up with a way to organize. It contains 58 methods, 38 of which are 100% static methods, 7 of which should have been declared static but weren't, and the remainder are actually interacting with $this. All in all, this class must be incredibly fun".

Let's look at the now implementation:

class data{ // ... public static function now() { return date('Y', time())."-".date('m', time())."-".date('d')." ".date('H').":".date('i').":".date('s'); }}

Finally, we get to your traditional bad date handling code. Instead of just using a date format string to get the desired output, we manually construct the string by invoking date a bunch of times. There are some interesting" choices here- you'll note that the PHP date function accepts a date parameter- so you can format an arbitrary date- and sometimes they pass in the result of calling time() and sometimes they don't. This is mostly not a problem, since date will invoke time itself if you don't hand it one, so that's just unnecessary.

But Vania adds some detail:

Because of the multiple calls to time() this code contains a subtle race condition. If it is called at, say, 2019-12-31 23:59:59.999, the date('Y', time()) part will evaluate to 2019". If the time now ticks over to 2020-01-01 00:00:00.000, the next date() call will return a month value of 01" (and so on for the rest of the expression). The result is a timestamp of 2019-01-01 00:00:00", which is off by a year. A similar issue happens at the end of every month, day, hour, and minute; i.e. every minute there is an opportunity for the result to be off by a minute.

It's easy to fix, of course, you could just: return date('Y-m-d H:i:s');, which does exactly the same thing, but correctly. Unfortunately, Vania has this to add:

Unfortunately there is no budget for making this kind of change to the application. Also, its original authors seem to have been a fan of code reuse" by copy/paste: There are four separate instances of this now() function in the codebase, all containing exactly the same code.

buildmaster-icon.png [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today! TheDailyWtf?d=yIl2AUoC8zAEDb55FvhCLQ
External Content
Source RSS or Atom Feed
Feed Location http://syndication.thedailywtf.com/TheDailyWtf
Feed Title The Daily WTF
Feed Link http://thedailywtf.com/
Reply 0 comments