public class DateTransform
public static void Main()
new DateTransform("2015-07-01", "2015-07-04");
new DateTransform("2015-12-01", "2016-02-03");
new DateTransform("2015-12-01", "2017-02-03");
new DateTransform("2016-03-01", "2016-05-05");
new DateTransform("2017-01-01", "2017-01-01");
new DateTransform("2022-09-05", "2023-09-04");
new DateTransform("2015-04-01", "2020-09-10");
new DateTransform("2015-12-11", "2016-12-11");
public DateTransform(string start, string end)
var startDate = DateTime.Parse(start);
var endDate = DateTime.Parse(end);
var startDateRep = new StartDateRepresentation(startDate, endDate);
var endDateRep = new EndDateRepresentation(startDate, endDate);
var output = startDateRep.ToString();
output = string.Format("{0} - {1}", output, endDateRep.ToString());
Console.WriteLine(output);
public class StartDateRepresentation
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public bool StartYearCurrentYear { get { return StartDate.Year == DateTime.Today.Year; } }
public bool SameYear { get { return StartDate.Year == EndDate.Year; } }
public bool SameMonth { get { return SameYear && StartDate.Month == EndDate.Month; } }
public bool SameDate { get { return StartDate == EndDate; } }
public bool AtLeastYearApart { get { return (EndDate.Year - StartDate.Year > 1) || (StartDate.Year == EndDate.Year -1) && ((StartDate.Month < EndDate.Month) || (StartDate.Month == EndDate.Month && StartDate.Date < EndDate.Date)); } }
public virtual bool ShowYear
if(SameDate) return true;
else if(SameYear) return false;
return !StartYearCurrentYear || (StartYearCurrentYear && AtLeastYearApart);
public StartDateRepresentation(DateTime startDate, DateTime endDate)
public override string ToString()
var month = StartDate.ToString("MMMM");
var output = string.Format("{0} {1}", month, StartDate.ToStringWithOrdinal());
if(ShowYear) output += string.Format(", {0}", StartDate.Year);
public class EndDateRepresentation : StartDateRepresentation
public override bool ShowYear
if(!StartYearCurrentYear && !AtLeastYearApart) return true;
if(SameYear) return false;
return !StartYearCurrentYear || (StartYearCurrentYear && AtLeastYearApart);
public EndDateRepresentation(DateTime startDate, DateTime endDate) : base(startDate, endDate)
public override string ToString()
var month = EndDate.ToString("MMMM");
var output = string.Empty;
if(SameMonth) output = EndDate.ToStringWithOrdinal();
else output = string.Format("{0} {1}", month, EndDate.ToStringWithOrdinal());
if(ShowYear) output += string.Format(", {0}", EndDate.Year);
public static class Extensions
public static string ToStringWithOrdinal(this DateTime d)
case 1: case 21: case 31:
return d.ToString("d'st'");
return d.ToString("d'nd'");
return d.ToString("d'rd'");
return d.ToString("d'th'");