2010-09-22 158 views
2

如何准确计算日,月,年?计算日,月,年

手段..

二路从1990年1月至2009年5月9日是..

XXX天,XXX月,XXX年。

任何想法如何做到这一点?

我想时间跨度和蜱()..双方未能如愿..

+0

你想得到什么:(2008,2,29) - >(2009,2,28)和(2008,2,28) - >(2009,2,28)。我认为TimeSpan不支持年份和月份,因为含糊不清,计算取决于日期差异的定义。 – 2010-09-22 07:06:06

回答

3

你不能做到这一点通过直接计算(即没有“TotalMonths”或TimeSpan“TotalYears”属性,仅仅是因为这些数字没有任何意义的时间间隔)。

相反,你可以指望的数量在一个循环中,像这样:

var dt1 = new DateTime(1990, 1, 2); 
var dt2 = new DateTime(2009, 5, 9); 

int years = 0; 
while (dt1.AddYears(1) < dt2) 
{ 
    years ++; 
    dt1 = dt1.AddYears(1); 
} 

int months = 0; 
while (dt1.AddMonths(1) < dt2) 
{ 
    months ++; 
    dt1 = dt1.AddMonths(1); 
} 

int days = (int) Math.Floor(dt2.Subtract(dt1).TotalDays); 

我没有测试过这一点,所以有可能是关闭的情况的一个错误或什么的,但是这是最基本的理念。

+1

我相信这个“​​保持增加一个”的方法存在一个基本问题 - 请参阅我的答案了解详情。 – 2010-09-22 06:38:19

+0

@Jon:是的,我认为你是对的...... – 2010-09-22 06:40:06

+0

IT工作.. – william 2010-09-22 07:03:45

6

我不认为框架中有任何内容可以做到这一点。 TimeSpan不会这样做,因为天数等取决于确切的起点和终点,而不仅仅是它们之间的持续时间。

下面是做这件事的简单方式,但效率不高:

using System; 

class Program 
{ 
    static void Main() 
    { 
     ShowDifference(new DateTime(1990, 1, 2), 
         new DateTime(2009, 5, 9)); 
    } 

    static void ShowDifference(DateTime start, 
           DateTime end) 
    { 
     if (start > end) 
     { 
      throw new ArgumentException(); 
     } 
     // See comment at the end 
     int years = end.Year - start.Year - 2; 
     while (start.AddYears(years) <= end) 
     { 
      years++; 
     } 
     years--; 
     Console.WriteLine("{0} years", years); 
     start = start.AddYears(years); 
     int months = 0; 
     while (start.AddMonths(months) <= end) 
     { 
      months++; 
     } 
     months--; 
     Console.WriteLine("{0} months", months); 
     start = start.AddMonths(months); 
     int days = 0; 
     while (start.AddDays(days) <= end) 
     { 
      days++; 
     } 
     days--; 
     Console.WriteLine("{0} days", days); 
    } 
} 

显然有使这种更有效的方式,但他们会繁琐。编辑:我已经改变了这种观点,并在年数方面进行了非常保守的猜测 - 它可能低于它需要的数量,但我现在不想考虑角落案例。它应该可以工作,并且这些循环都有(相当小的)上限来表示它们将运行的次数。

请注意,在每个步骤中,您应该将完整的年数/天/月数添加到起点,而不是一次只做一个月。否则,如果从1月30日到3月30日,由于从1月30日到2月28日增加了一个月,那么它将要求2个月和2天,然后在2月28日到3月28日之间增加第二个月。

希望Noda Time将让这一切更容易,当我最终得到全面完成它:)

+0

很好的解决方案。但我认为计算月份和日期的差异会非常困难。为了计算O(1)中的年份差异,只考虑一种情况,因此方法本身将在不变的时间内运行。 – 2010-09-22 06:52:35

+0

@Makkam:是的,这当然是可行的。这只是一个比我现在试图在这个时候尝试做的更好的手段。 – 2010-09-22 07:00:39

+0

@Makkam:我用一种保守的妥协解决方案编辑了代码 - 我怀疑它仍然可以更高效,但我仍然确信它会工作,而且很简单:) – 2010-09-22 07:03:03

0

怎么这样呢?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace DateTimeTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var dt1 = new DateTime(1990, 1, 2); 
      var dt2 = new DateTime(2009, 5, 9); 

      int days = dt2.Day - dt1.Day; 
      int months = dt2.Month - dt1.Month; 
      int years = dt2.Year - dt1.Year; 

      if (months < 0) 
      { 
       months += 12; 
       years -= 1; 
      } 
      if (days < 0) 
      { 
       dt1.AddYears(years); 
       dt1.AddMonths(months); 
       days = dt2.Subtract(dt1).Days; 
       months -= 1; 
      } 

      Console.WriteLine("{0} Days, {1} Months, {2} Years", days, months, years); 
     } 
    } 
} 

输出

7 Days, 4 Months, 19 Years 

是输出你要找的人?取决于您想如何定义“月”,您可能需要一些额外的条件。