patterncsharpModerate
"Pretty" date generator
Viewed 0 times
prettydategenerator
Problem
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 = 1) {
if (years >= 2) {
stringy = years.ToString() + " years ago";
} else {
stringy = "1 year ago";
}
} else if (weeks >= 1) {
if ((days - weeks * 7) > 0) {
if ((days - weeks * 7) > 1) {
stringy = ", " + (days - weeks * 7).ToString() + " days";
} else {
stringy = ", " + (days - weeks * 7).ToString() + " day";
}
}
if (weeks >= 2) {
stringy = weeks.ToString() + " weeks" + stringy + " ago";
} else {
stringy = "1 week" + stringy + " ago";
}
} else if (days >= 1) {
if ((hours - days * 24) > 0) {
if ((hours - days * 24) > 1) {
stringy = ", " + (hours - days * 24).ToString() + " hours";
} else {
stringy = ", " + (hours - days * 24).ToString() + " hour";
}
}
if (days >= 2) {
stringy = days.ToString() + " days" + stringy + " ago";
} else {
stringy = "1 day" + stringy + " ago";
}
} else if (hours >= 1) {
if ((minutes - hours * 60) > 0) {
if ((minutes - hours * 60) > 1) {
stringy = ", " + (minutes -
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 = 1) {
if (years >= 2) {
stringy = years.ToString() + " years ago";
} else {
stringy = "1 year ago";
}
} else if (weeks >= 1) {
if ((days - weeks * 7) > 0) {
if ((days - weeks * 7) > 1) {
stringy = ", " + (days - weeks * 7).ToString() + " days";
} else {
stringy = ", " + (days - weeks * 7).ToString() + " day";
}
}
if (weeks >= 2) {
stringy = weeks.ToString() + " weeks" + stringy + " ago";
} else {
stringy = "1 week" + stringy + " ago";
}
} else if (days >= 1) {
if ((hours - days * 24) > 0) {
if ((hours - days * 24) > 1) {
stringy = ", " + (hours - days * 24).ToString() + " hours";
} else {
stringy = ", " + (hours - days * 24).ToString() + " hour";
}
}
if (days >= 2) {
stringy = days.ToString() + " days" + stringy + " ago";
} else {
stringy = "1 day" + stringy + " ago";
}
} else if (hours >= 1) {
if ((minutes - hours * 60) > 0) {
if ((minutes - hours * 60) > 1) {
stringy = ", " + (minutes -
Solution
- Use PascalCase for the method name
- Move the calc for years and months lower to be minutely "more efficient"
- Use inline
returnto reduces nesting
- Use ternary operator (
?:) for simple logic to reduceif/elseclutter
- Use the
formatoverride ofToString(string format)to reduce string concats
- Use
string.Formatwith 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 = 1) {
return string.Format("{0} year{1} ago", years, years >= 2 ? "s" : null);
}
double weeks = Math.Floor(diff.TotalDays/7);
if (weeks >= 1) {
double partOfWeek = days - weeks*7;
if (partOfWeek > 0) {
stringy = string.Format(", {0} day{1}", partOfWeek, partOfWeek > 1 ? "s" : null);
}
return string.Format("{0} week{1}{2} ago", weeks, weeks >= 2 ? "s" : null, stringy);
}
if (days >= 1) {
double partOfDay = hours - days*24;
if (partOfDay > 0) {
stringy = string.Format(", {0} hour{1}", partOfDay, partOfDay > 1 ? "s" : null);
}
return string.Format("{0} day{1}{2} ago", days, days >= 2 ? "s" : null, stringy);
}
if (hours >= 1) {
double partOfHour = minutes - hours*60;
if (partOfHour > 0) {
stringy = string.Format(", {0} minute{1}", partOfHour, partOfHour > 1 ? "s" : null);
}
return string.Format("{0} hour{1}{2} ago", hours, hours >= 2 ? "s" : null, stringy);
}
// Only condition left is minutes > 1
return minutes.ToString("# minutes ago");
}Code Snippets
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 <= 1) {
return "Just Now";
}
double years = Math.Floor(diff.TotalDays/365);
if (years >= 1) {
return string.Format("{0} year{1} ago", years, years >= 2 ? "s" : null);
}
double weeks = Math.Floor(diff.TotalDays/7);
if (weeks >= 1) {
double partOfWeek = days - weeks*7;
if (partOfWeek > 0) {
stringy = string.Format(", {0} day{1}", partOfWeek, partOfWeek > 1 ? "s" : null);
}
return string.Format("{0} week{1}{2} ago", weeks, weeks >= 2 ? "s" : null, stringy);
}
if (days >= 1) {
double partOfDay = hours - days*24;
if (partOfDay > 0) {
stringy = string.Format(", {0} hour{1}", partOfDay, partOfDay > 1 ? "s" : null);
}
return string.Format("{0} day{1}{2} ago", days, days >= 2 ? "s" : null, stringy);
}
if (hours >= 1) {
double partOfHour = minutes - hours*60;
if (partOfHour > 0) {
stringy = string.Format(", {0} minute{1}", partOfHour, partOfHour > 1 ? "s" : null);
}
return string.Format("{0} hour{1}{2} ago", hours, hours >= 2 ? "s" : null, stringy);
}
// Only condition left is minutes > 1
return minutes.ToString("# minutes ago");
}Context
StackExchange Code Review Q#2738, answer score: 11
Revisions (0)
No revisions yet.