Noda Time: Period.Between returning incorrect value

僤鯓⒐⒋嵵緔 提交于 2020-01-13 11:35:08

问题


I have a trouble with NodaTime lib. My goal: compute Year/Month/Date between two dates. So, here is my test example:

    private static void Main()
    {
        var list = new List<Tuple<DateTime, DateTime>>
        {
            new Tuple<DateTime, DateTime>(new DateTime(1980, 1, 1), new DateTime(1983, 12, 31)),
            new Tuple<DateTime, DateTime>(new DateTime(2009, 1, 1), new DateTime(2015, 01, 23))
        };
        var totalPeriod = Period.Zero;
        foreach (var tuple in list)
        {
            var dateFrom = tuple.Item1;
            var dateTo = tuple.Item2;
            var ld1 = new LocalDate(dateFrom.Year, dateFrom.Month, dateFrom.Day);
            var ld2 = new LocalDate(dateTo.Year, dateTo.Month, dateTo.Day);
            var period = Period.Between(ld1, ld2, PeriodUnits.YearMonthDay);
            totalPeriod += period;
        }
        Console.WriteLine("Years: {0}, Months: {1}, Days: {2}", 
            totalPeriod.Years, 
            totalPeriod.Months,
            totalPeriod.Days);
        Console.Read();
    }

The output is: Years: 9, Months: 11, Days: 52

It's wrong for me. I want to get, for example, the next output (Of course, the output depends on number of days in month, assuming that there are 31 days in our month): Years: 10, Months: 0, Days: 21

So, I want that days was rounded to years and month. How I can get this?

The answer: Using Matt's answer I created the next solution:

 foreach (var tuple in list)
        {
            var dateFrom = tuple.Item1;
            var dateTo = tuple.Item2;
            var period = Period.Between(LocalDateTime.FromDateTime(dateFrom).Date, LocalDateTime.FromDateTime(dateTo).Date, PeriodUnits.YearMonthDay);
            totalPeriod += period;
        }
        // trying clarify the period
        while(totalPeriod.Days >= 30)
        {
            totalPeriod = totalPeriod - Period.FromDays(30);
            totalPeriod = totalPeriod + Period.FromMonths(1);
            while (totalPeriod.Months >= 12)
            {
                totalPeriod = totalPeriod - Period.FromMonths(12);
                totalPeriod = totalPeriod + Period.FromYears(1);
            }
        }

回答1:


Richard was right in his comment on the OP. The problem is that the months and years aren't distinct quantities unto themselves. One must have a frame of reference to "count" them. You have that reference when you do the Period.Between operation, but it's lost by the time you try to add the periods together.

If you check the periods that are being added, it makes sense:

First:  Years: 3, Months: 11, Days: 30
Second: Years: 6, Months: 0,  Days: 22
Total:  Years: 9, Months: 11, Days: 52

In order to round as you would like, the 22 days being added to the 30 days would somehow have to know which month was being referenced. Even if you retained the original information - which one would you use? You could well have a 28-day month on one side, and a 31-day month on the other.

The best you could do would be to artificially round the results yourself afterwards, and choose a flat value (such as 30 days) to represent all months.

Oh, one minor thing (unrelated to your question) - To go from a DateTime to a LocalDate, try LocalDateTime.FromDateTime(dt).Date. :)



来源:https://stackoverflow.com/questions/28102601/noda-time-period-between-returning-incorrect-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!