"Pretty" date generator I have this "pretty" date string generator in C# - pass it a date and it returns a string with "5 minutes ago" or "2 weeks, 3 days ago", etc.

It's a little verbose and hogs 61 lines, and I'm wondering if I'm missing out on some nice C# features or something. What (if any) is the best way to clean up this code? Are there any cool c# features I can use here?

public static string getTimeSpan(DateTime postDate)
{
    string stringy = "";
    TimeSpan diff = DateTime.Now.Subtract(postDate);
    double years = Math.Floor(diff.TotalDays / 365);
    double weeks = Math.Floor(diff.TotalDays / 7);
    double days = diff.Days;
    double hours = diff.Hours + days * 24;
    double minutes = diff.Minutes + hours * 60;
    if (minutes &lt;= 1) {
        stringy = "Just Now";
    } else if (years &gt;= 1) {
        if (years &gt;= 2) {
            stringy = years.ToString() + " years ago";
        } else {
            stringy = "1 year ago";
        }
    } else if (weeks &gt;= 1) {
        if ((days - weeks * 7) &gt; 0) {
            if ((days - weeks * 7) &gt; 1) {
                stringy = ", " + (days - weeks * 7).ToString() + " days";
            } else {
                stringy = ", " + (days - weeks * 7).ToString() + " day";
            }
        }
        if (weeks &gt;= 2) {
            stringy = weeks.ToString() + " weeks" + stringy + " ago";
        } else {
            stringy = "1 week" + stringy + " ago";
        }
    } else if (days &gt;= 1) {
        if ((hours - days * 24) &gt; 0) {
            if ((hours - days * 24) &gt; 1) {
                stringy = ", " + (hours - days * 24).ToString() + " hours";
            } else {
                stringy = ", " + (hours - days * 24).ToString() + " hour";
            }
        }
        if (days &gt;= 2) {
            stringy = days.ToString() + " days" + stringy + " ago";
        } else {
            stringy = "1 day" + stringy + " ago";
        }
    } else if (hours &gt;= 1) {
        if ((minutes - hours * 60) &gt; 0) {
            if ((minutes - hours * 60) &gt; 1) {
                stringy = ", " + (minutes - hours * 60).ToString() + " minutes";
            } else {
                stringy = ", " + (minutes - hours * 60).ToString() + " minute";
            }
        }
        if (hours &gt;= 2) {
            stringy = hours.ToString() + " hours" + stringy + " ago";
        } else {
            stringy = "1 hour" + stringy + " ago";
        }
    } else if (minutes &gt; 1) {
        stringy = minutes.ToString() + " minutes ago";
    }
    return stringy;
}
Use PascalCase for the method name
Move the calc for years and months lower to be minutely "more efficient"
Use inline return to reduces nesting
Use ternary operator (?:) for simple logic to reduce if/else clutter
Use the format override of ToString(string format) to reduce string concats
Use string.Format with a ternary to reduce duplication


The shorter version I came up with is 40 lines, but you can judge if it readable enough.

    public static string GetTimeSpan(DateTime postDate) {
        string stringy = string.Empty;
        TimeSpan diff = DateTime.Now.Subtract(postDate);
        double days = diff.Days;
        double hours = diff.Hours + days*24;
        double minutes = diff.Minutes + hours*60;
        if (minutes &lt;= 1) {
            return "Just Now";
        }
        double years = Math.Floor(diff.TotalDays/365);
        if (years &gt;= 1) {
            return string.Format("{0} year{1} ago", years, years &gt;= 2 ? "s" : null);
        }
        double weeks = Math.Floor(diff.TotalDays/7);
        if (weeks &gt;= 1) {
            double partOfWeek = days - weeks*7;
            if (partOfWeek &gt; 0) {
                stringy = string.Format(", {0} day{1}", partOfWeek, partOfWeek &gt; 1 ? "s" : null);
            }
            return string.Format("{0} week{1}{2} ago", weeks, weeks &gt;= 2 ? "s" : null, stringy);
        }
        if (days &gt;= 1) {
            double partOfDay = hours - days*24;
            if (partOfDay &gt; 0) {
                stringy = string.Format(", {0} hour{1}", partOfDay, partOfDay &gt; 1 ? "s" : null);
            }
            return string.Format("{0} day{1}{2} ago", days, days &gt;= 2 ? "s" : null, stringy);
        }
        if (hours &gt;= 1) {
            double partOfHour = minutes - hours*60;
            if (partOfHour &gt; 0) {
                stringy = string.Format(", {0} minute{1}", partOfHour, partOfHour &gt; 1 ? "s" : null);
            }
            return string.Format("{0} hour{1}{2} ago", hours, hours &gt;= 2 ? "s" : null, stringy);
        }

        // Only condition left is minutes &gt; 1
        return minutes.ToString("# minutes ago");
    }