关于C#:如何获得年/月/周/日中两个日期之间的差异?

How to get difference between two dates in Year/Month/Week/Day?

如何有效地获得年/月/周/日两个日期之间的差异?

两个日期的区别是1年,2个月,3周,4天。

差异表示两个日期之间的年、月、周和日的计数。


这实际上相当棘手。不同的总天数可能导致相同的结果。例如:

  • 2008年6月19日至2010年6月19日=2年,也为365*2天

  • 2006年6月19日至2008年6月19日=2年,但也有365+366天(闰年)

你很可能想减去年份,直到你得到两个相距不到一年的日期为止。然后减去月份,直到你得到两个相隔不到一个月的日期为止。

更令人困惑的是:当你可能以3月30日开始时,减法(或加)月是很棘手的——比这早一个月是什么?

更进一步的困惑(可能不相关):即使是一天也不总是24小时。日光节约有人吗?

更进一步的困惑(几乎肯定不相关):即使是一分钟也不总是60秒。闰秒是非常混乱的…

我现在没有时间想出正确的方法来解决这个问题——这个答案主要是为了说明这个问题并不像听起来那么简单。

编辑:很遗憾,我没有足够的时间来回答这个问题。我建议您首先定义一个表示Period的结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public struct Period
{
    private readonly int days;
    public int Days { get { return days; } }
    private readonly int months;
    public int Months { get { return months; } }
    private readonly int years;
    public int Years { get { return years; } }

    public Period(int years, int months, int days)
    {
        this.years = years;
        this.months = months;
        this.days = days;
    }

    public Period WithDays(int newDays)
    {
        return new Period(years, months, newDays);
    }

    public Period WithMonths(int newMonths)
    {
        return new Period(years, newMonths, days);
    }

    public Period WithYears(int newYears)
    {
        return new Period(newYears, months, days);
    }

    public static DateTime operator +(DateTime date, Period period)
    {
        // TODO: Implement this!
    }

    public static Period Difference(DateTime first, DateTime second)
    {
        // TODO: Implement this!
    }
}

我建议您先执行+运算符,它应该通知Difference方法—您应该确保first + (Period.Difference(first, second)) == second用于所有firstsecond值。

从编写一系列单元测试开始——最初是"简单"的案例,然后转向涉及闰年的棘手案例。我知道通常的方法是一次编写一个测试,但在您开始任何实现工作之前,我会亲自讨论其中的一些测试。

给自己一天时间来正确地执行这一点。这是棘手的事情。

请注意,我这里省略了周-这个值至少很容易,因为它总是7天。所以如果有一个(积极的)时期,你会:

1
2
3
4
int years = period.Years;
int months = period.Months;
int weeks = period.Days / 7;
int daysWithinWeek = period.Days % 7;

(我建议你甚至不要考虑消极的时期-确保所有的事情都是积极的,一直如此。)


部分是为了准备正确地回答这个问题(甚至可能是明确地…),部分是为了检查人们对粘贴在so上的代码的信任程度,部分是为了寻找bug,我为这个问题创建了一组单元测试,并将它们应用到本页的许多建议解决方案和几个副本中。S.好的。

结果是决定性的:没有一个代码贡献能准确回答这个问题。更新:我现在有四个正确的解决方案,包括我自己的,请参阅下面的更新。好的。代码测试

在这个问题上,我测试了以下用户的代码:Mohammed Ijas Nasirudeen,Ruffin,Malu MN,Dave,PK.,Jani,LC.好的。

这些答案在他们的代码中提供了三年、三个月和三天的时间。请注意,其中两个,Dave和Jani,给出了总天数和月数,而不是计算年份后剩余的总月数,以及计算月份后剩余的总天数。我认为答案是错误的,在什么样的OP似乎想要,但单元测试显然没有告诉你很多在这些情况下。(注意,在Jani的情况下,这是我的错误,他的代码实际上是正确的-见下面的更新4)好的。

乔恩·斯基特、阿加索莱玛尼、穆克什·库马尔、理查德、科林、舍尔(我刚才看到的)、乔基和安迪的回答都是不完整的。这并不意味着答案不好,事实上,其中有几个是对解决方案有用的贡献。这只是意味着没有代码可以接受两个DateTimes并返回3个ints,我可以适当地测试。然而,其中四个讨论使用TimeSpan。正如许多人所说,TimeSpan不会返回任何大于天的计数。好的。

我测试的其他答案来自好的。

  • 问题3054715-Lukeh,Ho1和此。怪人
  • 问题6260372-Chuck Rostance和Jani(与此问题的答案相同)
  • 问题9(!)-Dylan Hayes、Jon和Rajeshwaran S P

这个。好奇的极客的答案是他链接到的页面上的代码,我认为他没有写。Jani的答案是唯一一个使用外部库的答案,即.NET的时间段库。好的。

所有这些问题的其他答案似乎都不完整。问题9是关于年龄的问题,三个答案是超过了简单计算的年、月和日的答案。如果有人发现这个问题的更多副本,请告诉我。好的。我是如何测试的

很简单:我做了一个接口好的。

1
2
3
4
5
6
7
8
public interface IDateDifference
{
  void SetDates(DateTime start, DateTime end);
  int GetYears();
  int GetMonths();
  int GetDays();

}

对于每个答案,我都编写了一个实现这个接口的类,使用复制和粘贴的代码作为基础。当然,我必须调整具有不同签名等的函数,但我尝试进行最少的编辑,以保留所有的逻辑代码。好的。

我在抽象的泛型类中编写了一系列nunit测试好的。

1
2
[TestFixture]
public abstract class DateDifferenceTests<DDC> where DDC : IDateDifference, new()

并添加了一个空的派生类好的。

1
2
3
public class Rajeshwaran_S_P_Test : DateDifferenceTests<Rajeshwaran_S_P>
{
}

到每个IDateDifference类的源文件。好的。

努尼特聪明到可以做剩下的事。好的。测试

其中一些是预先编写的,其余的则是为了尝试并打破看似有效的实现而编写的。好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
[TestFixture]
public abstract class DateDifferenceTests<DDC> where DDC : IDateDifference, new()
{
  protected IDateDifference ddClass;

  [SetUp]
  public void Init()
  {
    ddClass = new DDC();
  }

  [Test]
  public void BasicTest()
  {
    ddClass.SetDates(new DateTime(2012, 12, 1), new DateTime(2012, 12, 25));
    CheckResults(0, 0, 24);
  }

  [Test]
  public void AlmostTwoYearsTest()
  {
    ddClass.SetDates(new DateTime(2010, 8, 29), new DateTime(2012, 8, 14));
    CheckResults(1, 11, 16);
  }

  [Test]
  public void AlmostThreeYearsTest()
  {
    ddClass.SetDates(new DateTime(2009, 7, 29), new DateTime(2012, 7, 14));
    CheckResults(2, 11, 15);
  }

  [Test]
  public void BornOnALeapYearTest()
  {
    ddClass.SetDates(new DateTime(2008, 2, 29), new DateTime(2009, 2, 28));
    CheckControversialResults(0, 11, 30, 1, 0, 0);
  }

  [Test]
  public void BornOnALeapYearTest2()
  {
    ddClass.SetDates(new DateTime(2008, 2, 29), new DateTime(2009, 3, 1));
    CheckControversialResults(1, 0, 0, 1, 0, 1);
  }


  [Test]
  public void LongMonthToLongMonth()
  {
    ddClass.SetDates(new DateTime(2010, 1, 31), new DateTime(2010, 3, 31));
    CheckResults(0, 2, 0);
  }

  [Test]
  public void LongMonthToLongMonthPenultimateDay()
  {
    ddClass.SetDates(new DateTime(2009, 1, 31), new DateTime(2009, 3, 30));
    CheckResults(0, 1, 30);
  }

  [Test]
  public void LongMonthToShortMonth()
  {
    ddClass.SetDates(new DateTime(2009, 8, 31), new DateTime(2009, 9, 30));
    CheckControversialResults(0, 1, 0, 0, 0, 30);
  }

  [Test]
  public void LongMonthToPartWayThruShortMonth()
  {
    ddClass.SetDates(new DateTime(2009, 8, 31), new DateTime(2009, 9, 10));
    CheckResults(0, 0, 10);
  }

  private void CheckResults(int years, int months, int days)
  {
    Assert.AreEqual(years, ddClass.GetYears());
    Assert.AreEqual(months, ddClass.GetMonths());
    Assert.AreEqual(days, ddClass.GetDays());
  }

  private void CheckControversialResults(int years, int months, int days,
    int yearsAlt, int monthsAlt, int daysAlt)
  {
    // gives the right output but unhelpful messages
    bool success = ((ddClass.GetYears() == years
                     && ddClass.GetMonths() == months
                     && ddClass.GetDays() == days)
                    ||
                    (ddClass.GetYears() == yearsAlt
                     && ddClass.GetMonths() == monthsAlt
                     && ddClass.GetDays() == daysAlt));

    Assert.IsTrue(success);
  }
}

大多数名称都有点傻,并不能真正解释为什么代码可能无法通过测试,但是查看两个日期和答案应该足以理解测试。好的。

有两种功能可以完成所有的AssertCheckResults()CheckControversialResults()。这些方法很好地保存了输入并给出了正确的结果,但不幸的是,它们使我们很难准确地看到出错的地方(因为CheckControversialResults()中的Assert将以"预期的正确"失败,而不是告诉您哪个值是错误的。如果有人有更好的方法(避免每次写相同的检查,但有更多有用的错误消息)请告诉我。好的。

CheckControversialResults()用于一些似乎对什么是正确有两种不同意见的情况。我有自己的观点,但我认为我在这里接受的东西应该是自由的。其要点是决定2月29日后一年是2月28日还是3月1日。好的。

这些测试是问题的关键,很可能存在错误,因此如果您发现错误,请发表评论。对于其他测试来说,听到一些建议来检查将来的答案迭代也会很好。好的。

没有测试涉及一天中的某个时间——所有的DateTime都在午夜。包括时间在内,只要能清楚地了解到每天的取整是如何工作的(我认为是这样),可能会出现更多的缺陷。好的。结果

结果的完整记分板如下:好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ChuckRostance_Test 3 failures               S S S F S S F S F
Dave_Test 6 failures                        F F S F F F F S S
Dylan_Hayes_Test 9 failures                 F F F F F F F F F
ho1_Test 3 failures                         F F S S S S F S S
Jani_Test 6 failures                        F F S F F F F S S
Jon_Test 1 failure                          S S S S S S F S S
lc_Test 2 failures                          S S S S S F F S S
LukeH_Test 1 failure                        S S S S S S F S S
Malu_MN_Test 1 failure                      S S S S S S S F S
Mohammed_Ijas_Nasirudeen_Test 2 failures    F S S F S S S S S
pk_Test 6 failures                          F F F S S F F F S
Rajeshwaran_S_P_Test 7 failures             F F S F F S F F F
ruffin_Test 3 failures                      F S S F S S F S S
this_curious_geek_Test 2 failures           F S S F S S S S S

但请注意,Jani的解决方案实际上是正确的,并且通过了所有测试——请参阅下面的更新4。好的。

列按测试名称的字母顺序排列:好的。

  • 至少三眼试验
  • 最早的
  • 基本测试
  • BornonaLeapYear测试
  • BornonaLeap年度测试2
  • 龙月
  • 长月时间长月时间
  • 从长月到短月
  • 长月至短月

三个答案只通过了一个测试,分别是乔恩、卢克和曼努。记住,这些测试可能是专门为解决这些答案的缺陷而写的。好的。

每个测试都通过了至少一段代码,这稍微让人放心,没有一个测试是错误的。好的。

有些答案没有通过很多测试。我希望没有人觉得这是对海报努力的谴责。首先,由于测试不能均匀地覆盖问题空间的问题区域,因此成功的次数是相当任意的。第二,这不是生产代码-答案是张贴的,所以人们可以从中学习,而不是复制到他们的程序中。很多测试都失败的代码中仍然有很好的想法。至少有一件测试失败了很多次,但其中有一个小缺陷,我没有修复。我很感谢那些花时间与其他人分享他们的工作的人,因为他们使这个项目如此有趣。好的。我的结论

有三种:好的。

  • 日历很难。我写了九个测试,包括三个有两个答案的测试。我只有一个答案的一些测试可能没有得到一致同意。在很多情况下,想清楚我们所说的"1个月后"或"2年前"是什么意思是很困难的。而且这些代码都不需要处理所有复杂的事情,比如在闰年的时候进行计算。所有这些都使用库代码来处理日期。如果你想象出用天、周、月和年来计算时间的"规格",那就有各种各样的粗糙。因为我们从小学起就非常了解它,并且每天都使用它,所以我们对许多特性视而不见。这个问题不是一个学术问题——在债券和其他金融产品的会计软件中,将时间段分解为年、季和月的各种类型是必不可少的。好的。

  • 写正确的代码是困难的。有很多虫子。在一些比较模糊的话题或者不那么流行的问题中,存在一个没有被评论者指出的bug的可能性要比这个问题高得多。你真的不应该,永远不要把代码从so复制到你的程序中,而不知道它到底做了什么。另一方面,你可能不应该在你的答案中写那些可以复制和粘贴的代码,而应该写一些智能的、有表现力的伪代码,这些伪代码允许人们理解解决方案并实现他们自己的版本(有他们自己的错误!)好的。

  • 单元测试很有用。我仍然打算在我谈到这个问题时发表我自己的解决方案(让其他人在其中找到隐藏的、不正确的假设!)这样做是"保存bug"的一个很好的例子,将它们转换成单元测试来修复下一个版本的代码。好的。

  • 更新

    整个项目现在位于https://github.com/jwg4/date-difference这包括我自己的尝试jwg.cs,它通过了我目前所有的测试,包括一些新的检查一天正确处理时间的测试。您可以随意添加更多的测试来打破这个和其他实现,或者添加更好的代码来回答这个问题。好的。更新2

    @mattjohnson添加了一个使用jon skeet的nodatime的实现。它通过了所有当前的测试。好的。更新3

    @Kirkwoll对两个日期之间几个月差异的回答已经添加到Github上的项目中。它通过了所有当前的测试。好的。更新4

    @贾尼在一篇评论中指出,我错误地使用了他的密码。他确实提出了正确计算年、月和日的方法(还有一些计算日和月总数的方法,而不是剩余的方法),但是我在测试代码中错误地使用了错误的方法。我已经更正了我对他的代码的包装,现在它通过了所有测试。现在有四个正确的解决方案,其中Jani是第一个。两个使用库(intenso.timeperiod和nodatime)和两个从头开始编写。好的。好啊。


    要正确计算年/月/周的差异,必须考虑CultureInfo的日历:

    • 闰年与非闰年
    • 不同天数的月份
    • 具有不同周数的年份(按周的第一天和日历周规则变化)

    .NET时间段库的datediff类考虑所有这些因素:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    // ----------------------------------------------------------------------
    public void DateDiffSample()
    {
      DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
      Console.WriteLine("Date1: {0}", date1 );
      // > Date1: 08.11.2009 07:13:59
      DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
      Console.WriteLine("Date2: {0}", date2 );
      // > Date2: 20.03.2011 19:55:28

      DateDiff dateDiff = new DateDiff( date1, date2 );

      // differences
      Console.WriteLine("DateDiff.Years: {0}", dateDiff.Years );
      // > DateDiff.Years: 1
      Console.WriteLine("DateDiff.Quarters: {0}", dateDiff.Quarters );
      // > DateDiff.Quarters: 5
      Console.WriteLine("DateDiff.Months: {0}", dateDiff.Months );
      // > DateDiff.Months: 16
      Console.WriteLine("DateDiff.Weeks: {0}", dateDiff.Weeks );
      // > DateDiff.Weeks: 70
      Console.WriteLine("DateDiff.Days: {0}", dateDiff.Days );
      // > DateDiff.Days: 497
      Console.WriteLine("DateDiff.Weekdays: {0}", dateDiff.Weekdays );
      // > DateDiff.Weekdays: 71
      Console.WriteLine("DateDiff.Hours: {0}", dateDiff.Hours );
      // > DateDiff.Hours: 11940
      Console.WriteLine("DateDiff.Minutes: {0}", dateDiff.Minutes );
      // > DateDiff.Minutes: 716441
      Console.WriteLine("DateDiff.Seconds: {0}", dateDiff.Seconds );
      // > DateDiff.Seconds: 42986489

      // elapsed
      Console.WriteLine("DateDiff.ElapsedYears: {0}", dateDiff.ElapsedYears );
      // > DateDiff.ElapsedYears: 1
      Console.WriteLine("DateDiff.ElapsedMonths: {0}", dateDiff.ElapsedMonths );
      // > DateDiff.ElapsedMonths: 4
      Console.WriteLine("DateDiff.ElapsedDays: {0}", dateDiff.ElapsedDays );
      // > DateDiff.ElapsedDays: 12
      Console.WriteLine("DateDiff.ElapsedHours: {0}", dateDiff.ElapsedHours );
      // > DateDiff.ElapsedHours: 12
      Console.WriteLine("DateDiff.ElapsedMinutes: {0}", dateDiff.ElapsedMinutes );
      // > DateDiff.ElapsedMinutes: 41
      Console.WriteLine("DateDiff.ElapsedSeconds: {0}", dateDiff.ElapsedSeconds );
      // > DateDiff.ElapsedSeconds: 29

      // description
      Console.WriteLine("DateDiff.GetDescription(1): {0}", dateDiff.GetDescription( 1 ) );
      // > DateDiff.GetDescription(1): 1 Year
      Console.WriteLine("DateDiff.GetDescription(2): {0}", dateDiff.GetDescription( 2 ) );
      // > DateDiff.GetDescription(2): 1 Year 4 Months
      Console.WriteLine("DateDiff.GetDescription(3): {0}", dateDiff.GetDescription( 3 ) );
      // > DateDiff.GetDescription(3): 1 Year 4 Months 12 Days
      Console.WriteLine("DateDiff.GetDescription(4): {0}", dateDiff.GetDescription( 4 ) );
      // > DateDiff.GetDescription(4): 1 Year 4 Months 12 Days 12 Hours
      Console.WriteLine("DateDiff.GetDescription(5): {0}", dateDiff.GetDescription( 5 ) );
      // > DateDiff.GetDescription(5): 1 Year 4 Months 12 Days 12 Hours 41 Mins
      Console.WriteLine("DateDiff.GetDescription(6): {0}", dateDiff.GetDescription( 6 ) );
      // > DateDiff.GetDescription(6): 1 Year 4 Months 12 Days 12 Hours 41 Mins 29 Secs
    } // DateDiffSample

    datediff还计算季度差异。


    闰年和不平衡的月份实际上使这成为一个不平凡的问题。我相信有人能想出一个更有效的方法,但这里有一个选择-先从小的方面进行近似,然后调整(未经测试):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public static void GetDifference(DateTime date1, DateTime date2, out int Years,
        out int Months, out int Weeks, out int Days)
    {
        //assumes date2 is the bigger date for simplicity

        //years
        TimeSpan diff = date2 - date1;
        Years = diff.Days / 366;
        DateTime workingDate = date1.AddYears(Years);

        while(workingDate.AddYears(1) <= date2)
        {
            workingDate = workingDate.AddYears(1);
            Years++;
        }

        //months
        diff = date2 - workingDate;
        Months = diff.Days / 31;
        workingDate = workingDate.AddMonths(Months);

        while(workingDate.AddMonths(1) <= date2)
        {
            workingDate = workingDate.AddMonths(1);
            Months++;
        }

        //weeks and days
        diff = date2 - workingDate;
        Weeks = diff.Days / 7; //weeks always have 7 days
        Days = diff.Days % 7;
    }


    使用System.Data.Linq名称空间及其SqlMethods.DateDiffMonth方法怎么样?

    例如,说:

    1
    2
    DateTime starDT = {01-Jul-2009 12:00:00 AM}
    DateTime endDT = {01-Nov-2009 12:00:00 AM}

    然后:

    1
    int monthDiff = System.Data.Linq.SqlClient.SqlMethods.DateDiffMonth(startDT, endDT);

    = 4

    SqlMethods类中还有其他DateDiff静态方法。


    减去两个DateTime实例,得到具有Days属性的TimeSpan。(例如,在PowerShell中):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    PS > ([datetime]::today - [datetime]"2009-04-07")


    Days              : 89
    Hours             : 0
    Minutes           : 0
    Seconds           : 0
    Milliseconds      : 0
    Ticks             : 76896000000000
    TotalDays         : 89
    TotalHours        : 2136
    TotalMinutes      : 128160
    TotalSeconds      : 7689600
    TotalMilliseconds : 7689600000

    将几天转换为几年或几周相对容易(一年中的几天可以是365天、365.25天,……取决于上下文)。月份要困难得多,因为没有基准日期,你不知道哪一个月的长度适用。

    假设您想从基准日期开始,您可以在计算第一年(检查闰年)、月份长度(从startdate.month开始索引)、周(剩余天数除以7)和天(剩余天数)的同时,递增地进行减法。

    有很多边缘案例需要考虑,例如,2005-03-01是2004-03-01的一年,2004-02-29取决于你所说的"年"。


    好吧,@jon skeet,如果我们不担心得到更多的粒度超过天(并且仍然将天滚动成更大的单位,而不是总的天数),根据Op,这在C中并没有那么困难。使日期数学如此困难的是,每个组合单元中的单元数经常发生变化。想象一下,如果每3加仑汽油只有3夸脱,但每12夸脱只有7夸脱,除了星期五,当……

    幸运的是,日期只是通过最大整数函数的一个很长的过程。这些疯狂的例外是令人发狂的,除非你已经一路走过古怪的组成单位,当它不再是一个大问题。如果你出生在1900年12月25日,那么不管你经历了多少闰年、几秒钟或者白天的节约期,你在2000年12月25日仍然是100岁。一旦你仔细研究了构成最后一个合成单元的百分比,你就回到了统一。你已经添加了一个,重新开始。

    也就是说,如果你在做数年到数月到数天的工作,唯一奇怪的组成单位就是月(天)。如果你需要从月值中借钱来处理一个你减去的天数比实际天数多的地方,你只需要知道上个月的天数。其他异常值都不重要。

    C在system.datetime.daysinmonth(intyear,intmonth)中给出了这个值。

    (如果您现在的月份小于您当时的月份,则没有问题。每年有12个月。)

    同样的道理,如果我们更细化…您只需要知道最后一个(复合单元)中有多少(小单元)。一旦你通过,你会得到另一个整数值(复合单位)。然后减去你错过了多少个小单位,从那时开始,然后再加上你现在错过了多少个组合单位。

    这是我第一次减掉两次约会的结果。它可能会起作用。希望有用。

    (编辑:将newmonth>oldmonth检查更改为newmonth>=oldmonth,因为如果月份相同,我们不需要借用一个(同上,用于天)。也就是说,2011年11月11日减去2010年11月9日是一年,12个月,2天(也就是说,2天,但是我们借的皇室在皇室不需要的时候。)

    (编辑:必须检查month=month,当我们需要借用days从dtenow.day&dtenow.day

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    private void Form1_Load(object sender, EventArgs e) {
    DateTime dteThen = DateTime.Parse("3/31/2010");
    DateTime dteNow = DateTime.Now;

    int intDiffInYears = 0;
    int intDiffInMonths = 0;
    int intDiffInDays = 0;


    if (dteNow.Month >= dteThen.Month)
    {
        if (dteNow.Day >= dteThen.Day)
        {   // this is a best case, easy subtraction situation
            intDiffInYears = dteNow.Year - dteThen.Year;
            intDiffInMonths = dteNow.Month - dteThen.Month;
            intDiffInDays = dteNow.Day - dteThen.Day;
        }
        else
        {   // else we need to substract one from the month diff (borrow the one)
            // and days get wacky.

            // Watch for the outlier of Month = Month with DayNow < DayThen, as then we've
            // got to subtract one from the year diff to borrow a month and have enough
            // days to subtract Then from Now.
            if (dteNow.Month == dteThen.Month)
            {
                intDiffInYears = dteNow.Year - dteThen.Year - 1;
                intDiffInMonths = 11; // we borrowed a year and broke ONLY
                // the LAST month into subtractable days
                // Stay with me -- because we borrowed days from the year, not the month,
                // this is much different than what appears to be a similar calculation below.
                // We know we're a full intDiffInYears years apart PLUS eleven months.
                // Now we need to know how many days occurred before dteThen was done with
                // dteThen.Month.  Then we add the number of days we've"earned" in the current
                // month.  
                //
                // So 12/25/2009 to 12/1/2011 gives us
                // 11-9 = 2 years, minus one to borrow days = 1 year difference.
                // 1 year 11 months - 12 months = 11 months difference
                // (days from 12/25 to the End Of Month) + (Begin of Month to 12/1) =
                //                (31-25)                +       (0+1)              =
                //                   6                   +         1                =
                //                                  7 days diff
                //
                // 12/25/2009 to 12/1/2011 is 1 year, 11 months, 7 days apart.  QED.

                int intDaysInSharedMonth = System.DateTime.DaysInMonth(dteThen.Year, dteThen.Month);
                intDiffInDays = intDaysInSharedMonth - dteThen.Day + dteNow.Day;
            }
            else
            {
                intDiffInYears = dteNow.Year - dteThen.Year;
                intDiffInMonths = dteNow.Month - dteThen.Month - 1;

                // So now figure out how many more days we'd need to get from dteThen's
                // intDiffInMonth-th month to get to the current month/day in dteNow.
                // That is, if we're comparing 2/8/2011 to 11/7/2011, we've got (10/8-2/8) = 8
                // full months between the two dates.  But then we've got to go from 10/8 to
                // 11/07.  So that's the previous month's (October) number of days (31) minus
                // the number of days into the month dteThen went (8), giving the number of days
                // needed to get us to the end of the month previous to dteNow (23).  Now we
                // add back the number of days that we've gone into dteNow's current month (7)
                // to get the total number of days we've gone since we ran the greatest integer
                // function on the month difference (23 to the end of the month + 7 into the
                // next month == 30 total days.  You gotta make it through October before you
                // get another month, G, and it's got 31 days).

                int intDaysInPrevMonth = System.DateTime.DaysInMonth(dteNow.Year, (dteNow.Month - 1));
                intDiffInDays = intDaysInPrevMonth - dteThen.Day + dteNow.Day;
            }
        }
    }
    else
    {
        // else dteThen.Month > dteNow.Month, and we've got to amend our year subtraction
        // because we haven't earned our entire year yet, and don't want an obo error.
        intDiffInYears = dteNow.Year - dteThen.Year - 1;

        // So if the dates were THEN: 6/15/1999 and NOW: 2/20/2010...
        // Diff in years is 2010-1999 = 11, but since we're not to 6/15 yet, it's only 10.
        // Diff in months is (Months in year == 12) - (Months lost between 1/1/1999 and 6/15/1999
        // when dteThen's clock wasn't yet rolling == 6) = 6 months, then you add the months we
        // have made it into this year already.  The clock's been rolling through 2/20, so two months.
        // Note that if the 20 in 2/20 hadn't been bigger than the 15 in 6/15, we're back to the
        // intDaysInPrevMonth trick from earlier.  We'll do that below, too.
        intDiffInMonths = 12 - dteThen.Month + dteNow.Month;

        if (dteNow.Day >= dteThen.Day)
        {
            intDiffInDays = dteNow.Day - dteThen.Day;
        }
        else
        {
            intDiffInMonths--;  // subtract the month from which we're borrowing days.

            // Maybe we shoulda factored this out previous to the if (dteNow.Month > dteThen.Month)
            // call, but I think this is more readable code.
            int intDaysInPrevMonth = System.DateTime.DaysInMonth(dteNow.Year, (dteNow.Month - 1));
            intDiffInDays = intDaysInPrevMonth - dteThen.Day + dteNow.Day;
        }

    }

    this.addToBox("Years:" + intDiffInYears +" Months:" + intDiffInMonths +" Days:" + intDiffInDays); // adds results to a rich text box.

    }

    1
    2
    3
    4
    DateTime dt1 = new DateTime(2009, 3, 14);
    DateTime dt2 = new DateTime(2008, 3, 15);

    int diffMonth = Math.Abs((dt2.Year - dt1.Year)*12 + dt1.Month - dt2.Month)

    如果减去两个EDOCX1的实例(0),则返回一个TimeSpan实例,表示两个日期之间的差异。


    我在寻找解决类似问题的时候遇到了这篇文章。我试图以年、月、周和日为单位来确定动物的年龄。这些值随后显示在spinedits中,用户可以手动更改这些值以查找/估计出生日期。当我的表格通过出生日期从一个月不到31天,计算值是1天休息。我的解决方案基于上述IC的答案。

    在窗体加载后调用的主要计算方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
            birthDateDisplay.Text = birthDate.ToString("MM/dd/yyyy");

            DateTime currentDate = DateTime.Now;

            Int32 numOfDays = 0;
            Int32 numOfWeeks = 0;
            Int32 numOfMonths = 0;
            Int32 numOfYears = 0;

            // changed code to follow this model http://stackoverflow.com/posts/1083990/revisions
            //years
            TimeSpan diff = currentDate - birthDate;
            numOfYears = diff.Days / 366;
            DateTime workingDate = birthDate.AddYears(numOfYears);

            while (workingDate.AddYears(1) <= currentDate)
            {
                workingDate = workingDate.AddYears(1);
                numOfYears++;
            }

            //months
            diff = currentDate - workingDate;
            numOfMonths = diff.Days / 31;
            workingDate = workingDate.AddMonths(numOfMonths);

            while (workingDate.AddMonths(1) <= currentDate)
            {
                workingDate = workingDate.AddMonths(1);
                numOfMonths++;
            }

            //weeks and days
            diff = currentDate - workingDate;
            numOfWeeks = diff.Days / 7; //weeks always have 7 days

            // if bday month is same as current month and bday day is after current day, the date is off by 1 day
            if(DateTime.Now.Month == birthDate.Month && DateTime.Now.Day < birthDate.Day)
                numOfDays = diff.Days % 7 + 1;
            else
                numOfDays = diff.Days % 7;

            // If the there are fewer than 31 days in the birth month, the date calculated is 1 off
            // Dont need to add a day for the first day of the month
            int daysInMonth = 0;
            if ((daysInMonth = DateTime.DaysInMonth(birthDate.Year, birthDate.Month)) != 31 && birthDate.Day != 1)
            {
                startDateforCalc = DateTime.Now.Date.AddDays(31 - daysInMonth);
                // Need to add 1 more day if it is a leap year and Feb 29th is the date
                if (DateTime.IsLeapYear(birthDate.Year) && birthDate.Day == 29)
                    startDateforCalc = startDateforCalc.AddDays(1);
            }

            yearsSpinEdit.Value = numOfYears;
            monthsSpinEdit.Value = numOfMonths;
            weeksSpinEdit.Value = numOfWeeks;
            daysSpinEdit.Value = numOfDays;

    然后,在我的spinedit?editValueChanged事件处理程序中,我根据旋转编辑中的值计算从startdateforcalc开始的新出生日期。(spinedit被约束为仅允许大于等于0)

    1
    2
    birthDate = startDateforCalc.Date.AddYears(-((Int32)yearsSpinEdit.Value)).AddMonths(-((Int32)monthsSpinEdit.Value)).AddDays(-(7 * ((Int32)weeksSpinEdit.Value) + ((Int32)daysSpinEdit.Value)));
    birthDateDisplay.Text = birthDate.ToString("MM/dd/yyyy");

    我知道这不是最漂亮的解决方案,但它似乎对我来说是一个月又一年的工作。


    1
    2
    3
    4
    5
    TimeSpan period = endDate.AddDays(1) - startDate;
    DateTime date = new DateTime(period.Ticks);
    int totalYears = date.Year - 1;
    int totalMonths = ((date.Year - 1) * 12) + date.Month - 1;
    int totalWeeks = (int)period.TotalDays / 7;

    日期。年份-1,因为年份0不存在。日期.月份-1,月份0不存在


    如果你必须找到原始日期和今天的日期之间的区别,这里有一个没有那么多条件检查的可靠算法。

  • 声明IntermediateDate变量并初始化为原始日期
  • 找出年份之间的差异。(yeardiff)
  • 将YearDiff添加到IntermediateDate并检查该值是否大于今天的日期。
  • 如果新获得的IntermediateDate>今天的日期,请按1调整YearDiff和IntermediateDate。
  • 在月和日继续上述步骤。
  • 我使用了system.data.linq函数来查找年、月和日的差异。请在下面找到C代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
            DateTime todaysDate = DateTime.Now;
            DateTime interimDate = originalDate;

            ///Find Year diff
            int yearDiff = System.Data.Linq.SqlClient.SqlMethods.DateDiffYear(interimDate, todaysDate);
            interimDate = interimDate.AddYears(yearDiff);
            if (interimDate > todaysDate)
            {
                yearDiff -= 1;
                interimDate = interimDate.AddYears(-1);
            }

            ///Find Month diff
            int monthDiff = System.Data.Linq.SqlClient.SqlMethods.DateDiffMonth(interimDate, todaysDate);
            interimDate = interimDate.AddMonths(monthDiff);
            if (interimDate > todaysDate)
            {
                monthDiff -= 1;
                interimDate = interimDate.AddMonths(-1);
            }

            ///Find Day diff
            int daysDiff = System.Data.Linq.SqlClient.SqlMethods.DateDiffDay(interimDate, todaysDate);


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {

            int gyear = dateTimePicker1.Value.Year;
            int gmonth = dateTimePicker1.Value.Month;
            int gday = dateTimePicker1.Value.Day;
            int syear = DateTime.Now.Year;
            int smonth = DateTime.Now.Month;
            int sday = DateTime.Now.Day;

            int difday = DateTime.DaysInMonth(syear, gmonth);

            agedisplay = (syear - gyear);

            lmonth = (smonth - gmonth);
            lday = (sday - gday);


            if (smonth < gmonth)
            {
                agedisplay = agedisplay - 1;
            }
            if (smonth == gmonth)
            {
                if (sday < (gday))
                {
                    agedisplay = agedisplay - 1;
                }
            }

            if (smonth < gmonth)
            {
                lmonth = (-(-smonth)+(-gmonth)+12);
            }
            if (lday < 0)
            {
                lday = difday - (-lday);
                lmonth = lmonth - 1;
            }

            if (smonth == gmonth && sday < gday&&gyear!=syear)
            {
                lmonth = 11;
            }

                ageDisplay.Text = Convert.ToString(agedisplay) +" Years, " + lmonth +" Months, " + lday +" Days.";

        }

    使用野田时间:

    1
    2
    3
    4
    5
    6
    7
    8
    var ld1 = new LocalDate(2012, 1, 1);
    var ld2 = new LocalDate(2013, 12, 25);
    var period = Period.Between(ld1, ld2);

    Debug.WriteLine(period);        //"P1Y11M24D"  (ISO8601 format)
    Debug.WriteLine(period.Years);  // 1
    Debug.WriteLine(period.Months); // 11
    Debug.WriteLine(period.Days);   // 24


    天:(结束日期-开始日期).days周:(结束日期-开始日期).days/7年:月/12月:时间跨度只提供天,因此使用以下代码获取指定开始日期和结束日期之间的整个月数。例如,2000年10月1日至2000年10月2日之间的整月数为1。2000年10月1日至2000年9月2日之间的整月数为0。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
        public int getMonths(DateTime startDate, DateTime endDate)
        {
            int months = 0;

            if (endDate.Month <= startDate.Month)
            {
                if (endDate.Day < startDate.Day)
                {
                    months = (12 * (endDate.Year - startDate.Year - 1))
                           + (12 - startDate.Month + endDate.Month - 1);
                }
                else if (endDate.Month < startDate.Month)
                {
                    months = (12 * (endDate.Year - startDate.Year - 1))
                           + (12 - startDate.Month + endDate.Month);
                }
                else  // (endDate.Month == startDate.Month) && (endDate.Day >= startDate.Day)
                {
                    months = (12 * (endDate.Year - startDate.Year));
                }
            }
            else if (endDate.Day < startDate.Day)
            {
                months = (12 * (endDate.Year - startDate.Year))
                       + (endDate.Month - startDate.Month) - 1;
            }
            else  // (endDate.Month > startDate.Month) && (endDate.Day >= startDate.Day)
            {
                months = (12 * (endDate.Year - startDate.Year))
                       + (endDate.Month - startDate.Month);
            }

            return months;
        }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    int day=0,month=0,year=0;
    DateTime smallDate = Convert.ToDateTime(string.Format("{0}","01.01.1900"));
    DateTime bigDate = Convert.ToDateTime(string.Format("{0}","05.06.2019"));
    TimeSpan timeSpan = new TimeSpan();

    //timeSpan is diff between bigDate and smallDate as days
    timeSpan = bigDate - smallDate;

    //year is totalDays / 365 as int
    year = timeSpan.Days / 365;

    //smallDate.AddYears(year) is closing the difference for year because we found the year variable
    smallDate = smallDate.AddYears(year);

    //again subtraction because we don't need the year now
    timeSpan = bigDate - smallDate;

    //month is totalDays / 30 as int
    month = timeSpan.Days / 30;

    //smallDate.AddMonths(month) is closing the difference for month because we found the month variable
    smallDate = smallDate.AddMonths(month);
    if (bigDate > smallDate)
    {
        timeSpan = bigDate - smallDate;
        day = timeSpan.Days;
    }
    //else it is mean already day is 0


    我试图找到一个明确的答案,多年,月和天,我没有发现任何明确的,如果你仍然在寻找,检查这个方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
            public static string GetDifference(DateTime d1, DateTime d2)
            {
                int[] monthDay = new int[12] { 31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                DateTime fromDate;
                DateTime toDate;
                int year;
                int month;
                int day;
                int increment = 0;

                if (d1 > d2)
                {
                    fromDate = d2;
                    toDate = d1;
                }
                else
                {
                    fromDate = d1;
                    toDate = d2;
                }

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

                if (increment == -1)
                {
                    if (DateTime.IsLeapYear(fromDate.Year))
                    {
                        increment = 29;
                    }
                    else
                    {
                        increment = 28;
                    }
                }

                if (increment != 0)
                {
                    day = (toDate.Day + increment) - fromDate.Day;
                    increment = 1;
                }
                else
                {
                    day = toDate.Day - fromDate.Day;
                }

                // Month Calculation
                if ((fromDate.Month + increment) > toDate.Month)
                {
                    month = (toDate.Month + 12) - (fromDate.Month + increment);
                    increment = 1;
                }
                else
                {
                    month = (toDate.Month) - (fromDate.Month + increment);
                    increment = 0;
                }

                // Year Calculation
                year = toDate.Year - (fromDate.Year + increment);

                return year +" years" + month +" months" + day +" days";
            }

    我有下面的解决方案,对我来说是正确的(在做了一些测试用例之后)。可以接受额外的测试用例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    public class DateDiffernce
    {
        private int m_nDays = -1;
        private int m_nWeek;
        private int m_nMonth = -1;
        private int m_nYear;

        public int Days
        {
            get
            {
                return m_nDays;
            }
        }

        public int Weeks
        {
            get
            {
                return m_nWeek;
            }
        }

        public int Months
        {
            get
            {
                return m_nMonth;
            }
        }

        public int Years
        {
            get
            {
                return m_nYear;
            }
        }

        public void GetDifferenceBetwwenTwoDate(DateTime objDateTimeFromDate, DateTime objDateTimeToDate)
        {
            if (objDateTimeFromDate.Date > objDateTimeToDate.Date)
            {
                DateTime objDateTimeTemp = objDateTimeFromDate;
                objDateTimeFromDate = objDateTimeToDate;
                objDateTimeToDate = objDateTimeTemp;
            }

            if (objDateTimeFromDate == objDateTimeToDate)
            {
                //textBoxDifferenceDays.Text =" Same dates";
                //textBoxAllDifference.Text =" Same dates";
                return;
            }

            // If From Date's Day is bigger than borrow days from previous month
            // & then subtract.
            if (objDateTimeFromDate.Day > objDateTimeToDate.Day)
            {
                objDateTimeToDate = objDateTimeToDate.AddMonths(-1);
                int nMonthDays = DateTime.DaysInMonth(objDateTimeToDate.Year, objDateTimeToDate.Month);
                m_nDays = objDateTimeToDate.Day + nMonthDays - objDateTimeFromDate.Day;

            }

            // If From Date's Month is bigger than borrow 12 Month
            // & then subtract.
            if (objDateTimeFromDate.Month > objDateTimeToDate.Month)
            {
                objDateTimeToDate = objDateTimeToDate.AddYears(-1);
                m_nMonth = objDateTimeToDate.Month + 12 - objDateTimeFromDate.Month;

            }

           //Below are best cases - simple subtraction
            if (m_nDays == -1)
            {
                m_nDays = objDateTimeToDate.Day - objDateTimeFromDate.Day;
            }

            if (m_nMonth == -1)
            {
                m_nMonth = objDateTimeToDate.Month - objDateTimeFromDate.Month;
            }

            m_nYear = objDateTimeToDate.Year - objDateTimeFromDate.Year;
            m_nWeek = m_nDays / 7;
            m_nDays = m_nDays % 7;    
        }
    }

    使用返回TimeSpanDateTime对象的Subtract方法…

    1
    2
    3
    4
    5
    6
    7
    8
    DateTime dt1 = new DateTime(2009, 3, 14);
    DateTime dt2 = new DateTime(2008, 3, 15);

    TimeSpan ts = dt1.Subtract(dt2);

    Double days = ts.TotalDays;
    Double hours = ts.TotalHours;
    Double years = ts.TotalDays / 365;


    基于Joaquim的答案,但在结束日期月份小于开始日期月份时修复计算,并添加代码以处理开始日期之前的结束日期:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
            public static class GeneralHelper
            {
              public static int GetYears(DateTime startDate, DateTime endDate)
                {
                    if (endDate < startDate)
                        return -GetYears(endDate, startDate);

                    int years = (endDate.Year - startDate.Year);

                    if (endDate.Year == startDate.Year)
                        return years;

                    if (endDate.Month < startDate.Month)
                        return years - 1;

                    if (endDate.Month == startDate.Month && endDate.Day < startDate.Day)
                        return years - 1;

                    return years;
                }

                public static int GetMonths(DateTime startDate, DateTime endDate)
                {
                    if (startDate > endDate)
                        return -GetMonths(endDate, startDate);

                    int months = 12 * GetYears(startDate, endDate);

                    if (endDate.Month > startDate.Month)
                        months = months + endDate.Month - startDate.Month;
                    else
                        months = 12 - startDate.Month + endDate.Month;

                    if (endDate.Day < startDate.Day)
                        months = months - 1;

                    return months;
                }
           }
        [TestClass()]
        public class GeneralHelperTest
        {
                [TestMethod]
                public void GetYearsTest()
                {
                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2000, 5, 5), new DateTime(2000, 12, 31)));
                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2000, 5, 5), new DateTime(2001, 4, 4)));
                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2000, 5, 5), new DateTime(2001, 5, 4)));
                    Assert.AreEqual(1, GeneralHelper.GetYears(new DateTime(2000, 5, 5), new DateTime(2001, 5, 5)));
                    Assert.AreEqual(1, GeneralHelper.GetYears(new DateTime(2000, 5, 5), new DateTime(2001, 12, 31)));

                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2000, 12, 31), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2001, 4, 4), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(0, GeneralHelper.GetYears(new DateTime(2001, 5, 4), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-1, GeneralHelper.GetYears(new DateTime(2001, 5, 5), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-1, GeneralHelper.GetYears(new DateTime(2001, 12, 31), new DateTime(2000, 5, 5)));
                }

                [TestMethod]
                public void GetMonthsTest()
                {
                    Assert.AreEqual(0, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2000, 6, 4)));
                    Assert.AreEqual(1, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2000, 6, 5)));
                    Assert.AreEqual(1, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2000, 6, 6)));
                    Assert.AreEqual(11, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2001, 5, 4)));
                    Assert.AreEqual(12, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2001, 5, 5)));
                    Assert.AreEqual(13, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2001, 6, 6)));

                    Assert.AreEqual(0, GeneralHelper.GetMonths(new DateTime(2000, 6, 4), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-1, GeneralHelper.GetMonths(new DateTime(2000, 6, 5), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-1, GeneralHelper.GetMonths(new DateTime(2000, 6, 6), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-11, GeneralHelper.GetMonths(new DateTime(2001, 5, 4), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-12, GeneralHelper.GetMonths(new DateTime(2001, 5, 5), new DateTime(2000, 5, 5)));
                    Assert.AreEqual(-13, GeneralHelper.GetMonths(new DateTime(2001, 6, 6), new DateTime(2000, 5, 5)));
                }
       }

    编辑"不",仍然不起作用。此测试失败:

    1
    Assert.AreEqual(24, GeneralHelper.GetMonths(new DateTime(2000, 5, 5), new DateTime(2003, 5, 5)));

    期望值:<24>。实际情况:< 12 >


    1
    2
    3
    4
    5
    6
    7
        Console.WriteLine("Enter your Date of Birth to Know your Current age in DD/MM/YY Format");
        string str = Console.ReadLine();
        DateTime dt1 = DateTime.Parse(str);
        DateTime dt2 = DateTime.Parse("10/06/2012");
        int result = (dt2 - dt1).Days;
        result = result / 365;
        Console.WriteLine("Your Current age is {0} years.",result);


    1
    2
    3
    4
    5
    6
    7
    8
    9
    DateTime startTime = DateTime.Now;

    DateTime endTime = DateTime.Now.AddSeconds( 75 );

    TimeSpan span = endTime.Subtract ( startTime );
     Console.WriteLine("Time Difference (seconds):" + span.Seconds );
     Console.WriteLine("Time Difference (minutes):" + span.Minutes );
     Console.WriteLine("Time Difference (hours):" + span.Hours );
     Console.WriteLine("Time Difference (days):" + span.Days );

    输出:

    1
    2
    3
    4
    Time Difference (seconds): 15
    Time Difference (minutes): 1
    Time Difference (hours): 0
    Time Difference (days): 0