Timespan年份和月份以十进制表示c#

Sag*_*esh 1 c# datetime timestamp

我有两个decimal

3.10m = 3 years 10 months 
 2.8m = 2 years  8 months.
Run Code Online (Sandbox Code Playgroud)

我正在尝试sum这些值,结果5.9不正确的.

预期的结果应该是

6.6m = 6 years 6 months
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议我们如何TimeSpan在C#中使用或以任何其他方式实现此目的.提前致谢

Jon*_*eet 5

首先,我会避免使用这样的小数来表示年/月值.如评论中所述,您将无法轻易区分1个月到10个月......虽然decimal 可以表示3.1和3.10之间的差异,但这将是一个非常奇怪的用法.只需将两个值保持为单独的整数即可.

接下来,你不能用这样做算术TimeSpan.A TimeSpan只存储"多个滴答" - 它不处理"1个月"或"1年"之类的想法,因为它们不代表固定数量的刻度.

我推荐使用我的Noda Time库.您将这些值表示为Period对象.您仍然无法直接添加年份和月份 - Period不会假设格里高利历法系统,并且这样的算术对某些非格里高利日历不起作用,特别是那些根据日期变化的月份日历那一年.但是,您可以轻松编写自己的Period规范化方法:

using System;
using NodaTime;

class Test
{
    static void Main()
    {
        Period p1 = new PeriodBuilder { Years = 3, Months = 10 }.Build();
        Period p2 = new PeriodBuilder { Years = 5, Months = -12 }.Build();
        Period sum = p1 + p2;
        Period normalized = NormalizeYearsAndMonths(sum);
        Console.WriteLine($"{normalized.Years} years; {normalized.Months} months");
    }

    static Period NormalizeYearsAndMonths(Period period)
    {
        // TODO: Handle negative years and months however you want.
        int years = period.Years;
        int months = period.Months;
        years += months / 12;
        months = months % 12;
        var builder = period.ToBuilder();
        builder.Years = years;
        builder.Months = months;
        return builder.Build();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当然,你可以只是把一切都在两个整数代替-使用的好处Period是,你可以很容易将它添加到一个LocalDate或者LocalDateTime等你甚至可以做,没有与正常化开始,如果你想.