【问题标题】:Errornous calculation of year/month/day between two dates两个日期之间的年/月/日计算错误
【发布时间】:2013-12-19 09:54:16
【问题描述】:

我尝试做的是计算两个日期之间的年数、月数和天数。 不幸的是,没有 .NET Framework 的方法可以做到这一点。

我所做的基本上如下: http://www.codeproject.com/Articles/28837/Calculating-Duration-Between-Two-Dates-in-Years-Mo

从所述网站的 cmets 中进行了一些改编:

var monthDay = new[] { 31, 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

日计算:

if (fromDate.Day > toDate.Day)
{
    increment = monthDay[toDate.Month - 1];
}

if (increment == -1)
{
    increment = DateTime.IsLeapYear(toDate.Year) ? 29 : 28;
}

所以我有以下效果:

日期1:1979-01-30

日期2:2013-03-01

输出为:34 Years, 1 Month, -1 Day

预期输出为:34 年 1 个月 1 天

这种效果每次都会发生,Date2 是三月的日期。

你知道这个计算有什么问题吗? 或者您知道更好的解决方案如何达到预期的效果?

提前致谢

PS:我知道你可以计算两个日期之间的天数,但我需要的是完成的年数、完成的月数和完成的天数

【问题讨论】:

    标签: c# .net date datetime


    【解决方案1】:

    不幸的是,.NET Framework 没有任何方法可以做到这一点。

    是的,但是 Noda Time 代替 :) (这是我将 Joda Time 移植到 .NET 的端口,尽管这两个项目之间存在不少差异。)

    LocalDate start = new LocalDate(1979, 1, 30);
    LocalDate end = new LocalDate(2013, 3, 1);
    Period period = Period.Between(start, end);
    Console.WriteLine("{0} years, {1} months, {2} days",
                      period.Years, period.Months, period.Days);
    

    输出:

    34 years, 1 months, 1 days
    

    【讨论】:

    • 我刚刚用 Noda Time 测试了我的测试用例,它就像一个魅力!非常感谢,不知道这个很棒的框架:-)
    • 嗨,乔恩,我在您的网站上没有找到任何有关 Noda Time 许可的信息……是否允许在商业项目中使用 Noda Time,或者有任何限制吗?提前致谢
    • @user3092518:它在 Apache 许可证下 - 在网站上搜索“许可证”以获取许可证详细信息的链接。
    【解决方案2】:

    这是一种无需使用外部库即可计算差异的方法。需要两个日期。我假设第一次约会不迟于第二次约会。否则,您必须交换它们才能使计算正确。

    var first = new DateTime(1979, 1, 30);
    var second = new DateTime(2013, 3, 1);
    

    这是计算差异的方法。您不需要表格来获取该月的天数。该信息由DateTime.DaysInMonth 函数提供。

    var years = second.Year - first.Year;
    var months = second.Month - first.Month;
    if (months < 0) {
      months += 12;
      years -= 1;
    }
    var days = second.Day - first.Day;
    if (days < 0) {
      var daysInFirstMonth = DateTime.DaysInMonth(first.Year, first.Month);
      days += daysInFirstMonth;
      months -= 1;
    }
    

    打印计算值

    Console.WriteLine("{0} year(s), {1} month(s), {2} day(s)", years, months, days);
    

    会导致

    34 年,1 个月,2 天

    这会产生与您链接到的代码相同的结果。但是,您希望得到 1 天而不是 2 天。我想这取决于您如何定义“间隔天数”。如果您希望仅将 1 月 31 日算作中间日期,则可以从 days 中减去 1。那么相邻两天之间会有0天,“同一日期之间”会有-1天。

    【讨论】:

    • Noda Time 至少产生 34 年 1 个月 1 天的原因是,加上 34 年,你会得到 2013-01-30;添加 1 个月后,您将获得 2013-02-28,然后添加 1 天后,您将获得 2013-03-01。目前还不清楚 2 天是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    相关资源
    最近更新 更多