一尘不染

用年格式化时间跨度

c#

我有一个带有2个日期属性的类:FirstDayLastDayLastDay为空。我想生成一个格式为的字符串"x year(s) y day(s)"。如果总年数少于1,我想省略年份部分。如果总天数少于1,我想省略“天”部分。如果年或天为0,则应分别说“天/年”,而不是“天/年”。

示例:
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;
    }
}

是否有更简洁的方法(但仍可读)?


阅读 319

收藏
2020-05-19

共1个答案

一尘不染

A TimeSpan没有明智的“年”概念,因为它取决于起点和终点。(几个月是相似的-29天内有多少个月?嗯,这取决于…)

为了提供一个无耻的插件,我的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
2020-05-19