Mohamad
Mohamad

Reputation: 35349

Can this date time function be written more efficiently?

The following function returns the difference between two date time values in words (as a string). Can it be written more efficiently/elegantly?

/**
* @hint Returns the difference between two time strings in words.
*/
public string function timeAgoInWords(required date fromTime, date toTime=now())
{
    local.secondDiff = dateDiff("s", arguments.fromTime, arguments.toTime);

    if (local.secondDiff <= 60)
        return "#local.secondDiff# seconds ago";

    local.minuteDiff = dateDiff("n", arguments.fromTime, arguments.toTime);

    if (local.minuteDiff <= 60)
        if (local.minuteDiff < 2)
            return "1 minute ago";
        else return "#local.minuteDiff# minutes ago";

    if (local.minuteDiff <= 1440)
        if (local.minuteDiff <= 120)
            return "1 hour ago";
        else return "#int(local.minuteDiff/60)# hours ago";

    if (local.minuteDiff <= 2880)
        return "yesterday";

    if (local.minuteDiff <= 4320)
        return "2 days ago";

    local.monthDiff = dateDiff("m", arguments.fromTime, arguments.toTime);

    if (local.monthDiff <= 12)
        return "#dateFormat(arguments.fromTime, "mmm dd")# at #timeFormat(arguments.fromTime, "h:mm")#";

    return "#dateFormat(arguments.fromTime, "mmm dd 'yy")# at #timeFormat(arguments.fromTime, "h:mm")#";
}

Upvotes: 1

Views: 242

Answers (2)

Henry
Henry

Reputation: 32915

This is what I wrote a few months ago, based on the UDF Al Everett posted above in the comment and written in CF9 script style. It won't be more efficient. In fact, it should be slower then your implementation 'cause it has multiple calls to dateDiff(), and needs to set up 2 arrays up front, but the overall line count is shorter and easily understandable.

string function ago(required Date dateThen)
{
    var dateparts = ["yyyy","m","d","h","n"];
    var datepartNames = ["year","month","day","hour","minute"];
    var rightNow = Now();

    for (var i = 1; i <= 5; i++)    // 5 == arrayLen(dateparts)
    {
        var diff = dateDiff(variables.dateparts[i], dateThen, rightNow);

        if (diff > 1)
            return "#diff# #datepartNames[i]#s ago";

        if (diff == 1)
            return "#diff# #datepartNames[i]# ago";
    }

    return "Just Now";
}

Upvotes: 3

AlbertVo
AlbertVo

Reputation: 772

It looks good to me. You could instead use your first diff (local.secondDiff) for all your tests rather than re-diffing, but this is probably easier to read.

Upvotes: 2

Related Questions