One of the more curious perversions in information technology I’ve come across was one that I’ve written myself. Maybe I’m biased, but it was pretty rough: a poorly-implemented, over-engineered solution to a misunderstood problem. I’ll get around to digging that up one of these days, but in the mean time I thought I’d try something new: Confessions.

Years ago, Harry Dewulf was the Javascript Guru. Not only could he work around bugs in vendor software (thanks to Javascript injection in form field labels), but he worked around bugs in Javascript itself. Consider, for example, his replacement for the defective parseInt function which frequently didn't work.

function r_parseInt(i)
{
    return parseInt(i,10);
}

Following the amazed success he received for that “gem”, he was encouraged to tackle Javascript’s unreliable Date object. You know, something that would compare dates and times in the way that the native object was meant to. Since he had an interest in mechanical timers, he came up with something that mimics the way that a mechanical calendar works and benefited from “the flexibility of virtualization.”

The result of this was the rachetingDateObject . This object contained the following child objects: yearWheel, monthWheel, monthWheell, 28DayWheel, 29DayWheel, 30DayWheel, 31DayWheel. When a daywheel reached the highest/lowest value, it tripped the month wheel, which then selected the proper day wheel for itself. Though the original code has been lost to time, it looked something like this.

rachetingDateObject.prototype.spinDaysUntil(lastDateYear, lastDateMonth, lastDateDay)
{
    this.resetDaysCount();
    while(!this.dateMatch(lastDateYear, lastDateMonth, lastDateDay))
    {
        this.currentDayWheel.spin(1);
    }
}

28DayWheel.prototype = new DayWheel();
28DayWheel.prototype.constructor = 28DayWheel;
function 28DayWheel()
{
    this.upperLimit = 29;
}
28DayWheel.new = function(p_rachetingDateObject,currentDay)
{
    var r = new 28DayWheel();
    this.parent = p_rachetingDateObject;
    this.spinTo(currentDay);
}

In a mechanical calendar you can't just "set" a value on a wheel. You have to rotate the wheel to the appropriate position. So logically to set the value of the day wheel you had to use the spin function to rotate it from the initial value (of 1) to the value of the currentDay. Here is what the spin function looked like:

DayWheel.prototype.spinTo = function(targetDay)
{
    while(this.currentDay!=targetDay)
    {	
        this.spin();
    }
}

DayWheel.prototype.spin = function(reverse)
{
    (reverse!=nothing)||(reverse=1);
    this.currentDay+=reverse;
    if(this.currentDay==this.upperLimit||this.currentDay==this.lowerLimit)
    {
        this.parent.spinMonth(reverse);
    }
}

When the month wheel passed the December/January mark, the year wheel would move, and select either monthWheel or monthWheell. To calculate the difference in days between two dates, all you had to do was put the first and last dates into the object, and then call the function spinDaysUntil(). This would advance the daywheel one day, and then compare the new date with the endDate. If it did not match, then it would advance by another day.

Harry is pretty sure the rachetingDateObject is still in use to this day as it always passed unit tests and would never need to be modified. It also has the advantage of being completely self-validating: if you attached a logger you could prove that not a single day was missed.


Have a confession you’d like to share? Drop me a line!

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!