我有一个带有2个日期属性的类:FirstDay和LastDay。 LastDay为空。我想生成一个格式为的字符串"x year(s) y day(s)"。如果总年数少于1,我想省略年份部分。如果总天数少于1,我想省略“天”部分。如果年或天为0,则应分别说“天/年”,而不是“天/年”。
FirstDay
LastDay
"x year(s) y day(s)"
示例: 2.2年:“ 2年73天” 1.002738年:“ 1年1 天” 0. 2年:“ 73天” 2年:“ 2年”
我所拥有的作品,但是很长:
private const decimal DaysInAYear = 365.242M; public string LengthInYearsAndDays { get { var lastDay = this.LastDay ?? DateTime.Today; var lengthValue = lastDay - this.FirstDay; var builder = new StringBuilder(); var totalDays = (decimal)lengthValue.TotalDays; var totalYears = totalDays / DaysInAYear; var years = (int)Math.Floor(totalYears); totalDays -= (years * DaysInAYear); var days = (int)Math.Floor(totalDays); Func<int, string> sIfPlural = value => value > 1 ? "s" : string.Empty; if (years > 0) { builder.AppendFormat( CultureInfo.InvariantCulture, "{0} year{1}", years, sIfPlural(years)); if (days > 0) { builder.Append(" "); } } if (days > 0) { builder.AppendFormat( CultureInfo.InvariantCulture, "{0} day{1}", days, sIfPlural(days)); } var length = builder.ToString(); return length; } }
是否有更简洁的方法(但仍可读)?
A TimeSpan没有明智的“年”概念,因为它取决于起点和终点。(几个月是相似的-29天内有多少个月?嗯,这取决于…)
TimeSpan
为了提供一个无耻的插件,我的Noda Time项目使这变得非常简单:
using System; using NodaTime; public class Test { static void Main(string[] args) { LocalDate start = new LocalDate(2010, 6, 19); LocalDate end = new LocalDate(2013, 4, 11); Period period = Period.Between(start, end, PeriodUnits.Years | PeriodUnits.Days); Console.WriteLine("Between {0} and {1} are {2} years and {3} days", start, end, period.Years, period.Days); } }
输出:
Between 19 June 2010 and 11 April 2013 are 2 years and 296 days