日期时间差异的恢复正确的几个月甚至几年?

是否有任何内置函数如何以更好的方式获得日期时间对象之间的区别? 我的意思是1个月,23天。 我觉得很难计算,因为每个月的天数不同,闰年等等。谢谢

看看Noda Time 。 一般来说它还没有生产就绪,但相关位可能足以满足您当前的要求:)

请注意, TimeSpan 不会执行您想要的操作,因为“1个月”可能意味着不同的天数,具体取决于月份,并且TimeSpan不会锚定。

在野田时间,你想要一个Period 。 例如:

 LocalDate start = new LocalDate(2010, 4, 15); LocalDate end = new LocalDate(2010, 6, 19); Period period = Period.Between(start, end); // Defaults to Year/Month/Day Console.WriteLine(period.Months); // 2 Console.WriteLine(period.Days); // 4 

请注意, 日期/时间算术很难 ……在某些情况下,“正确答案”并不明显。

月份可以包括28天,29天,30天或31天; 年可以是365天或366天。 因此,当您尝试计算几个月和几年的完整时间单位时会出现问题,因此,如果您可以假设某些内容,那么您可以查看

简单的减法将完成这项工作:

 int months = departure.Months - arrival.Months; int years = departure.Years - arrival.Years; //in case multiple years have elapsed . int months += years * 12; 

显然,你需要做几天的数学计算,如果你不关心精度如果日差是负的,你需要从月中减去一个。


然后你可以使用TimeSpan来获得更高的精度,也就是经过的时间。

 //Microsoft Documentation Example: DateTime departure = new DateTime(2010, 6, 12, 18, 32, 0); DateTime arrival = new DateTime(2010, 6, 13, 22, 47, 0); TimeSpan travelTime = arrival - departure; Console.WriteLine("{0} - {1} = {2}", arrival, departure, travelTime); // The example displays the following output: // 6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00 

对于日历日期来说,这种问题难以指定。 看看这里有一个很好的计算如何计算一个人的年龄。

用C#计算年龄

复杂性来自边缘情况。 显然,1月31日是12月31日之后的一个月。 但是,1月31日之后的一个月是2月28日? 在正常的一年? 在闰年? 在编写代码之前,您需要指定这些类型的案例。

生日算法使用向下舍入和递增策略。 鉴于您对前一段中的问题的回答,这对月份差异也有效。

以下是我刚才编写的一些代码,用于计算年,月和日的差异。 它属于公共领域。

  public sealed class DateDifference { int years; public int Years { get { return years; } } int months; public int Months { get { return months; } } int days; public int Days { get { return days; } } public override string ToString() { return string.Format("[DateDifference Years={0}, Months={1}, Days={2}]", years, months, days); } public DateDifference(DateTime earlier, DateTime later){ if(later 

例:

 var dd=new DateDifference(new DateTime(2010,6,29),new DateTime(2012,2,29)); Console.WriteLine(dd.Years); // displays 1 Console.WriteLine(dd.Months); // displays 8 Console.WriteLine(dd.Days); // displays 0 

您可以使用.NET时间段库的DateDiff类:

 // ---------------------------------------------------------------------- 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 } // DateDiffSample 

试试这个

  public string YearsMonthsDaysDiff(DateTime dateFrom, DateTime dateTo) { Int32 mD = DateTime.DaysInMonth(dateTo.Year, dateTo.AddMonths(-1).Month); //first check out days in month before dateTo month Int32 D1 = dateFrom.Day; Int32 M1 = dateFrom.Month; Int32 Y1 = dateFrom.Year; Int32 D2 = dateTo.Day; Int32 M2 = dateTo.Month; Int32 Y2 = dateTo.Year; // Substract each datetime components accordingly D2 -= D1; M2 -= M1; Y2 -= Y1; if (D2 < 0) { D2 += mD;// D2 is less then D1, then add mD M2 -= 1; // but, substract 1 from M2 } if (M2 < 0) { M2 += 12; // if M2 is less then M1, then add with 12 Y2 -= 1; // but substract 1 from Y2 } return Y2.ToString("## years ") + M2.ToString("## months ") + D2.ToString("## days"); } 

这对我来说可以

这是一个类,允许您查询一对DateTimes的差异的各种属性。 我现在只是掀起它,并将其发布到公共领域。 尽可能地使用它,但使用它需要您自担风险。

 public static class DateCalcs { ///  /// returns the integer number of years between start and finish ///  /// Start DateTime /// FinishDateTime ///  public static int YearDiff(DateTime start, DateTime finish) { DateTime _start, _finish; bool _negate = (finish < start); if(_negate) { _start = finish; _finish = start; } else { _start = start; _finish = finish; } int _diff = 0; while(_start.AddYears(1) < _finish) { _diff++; _start = _start.AddYears(1); } if(_negate) { _diff = _diff * (-1); } return _diff; } ///  /// returns the integer number of months between start and finish ///  /// Start DateTime /// Finish DateTime ///  public static int MonthDiff(DateTime start, DateTime finish) { DateTime _start, _finish; bool _negate = (finish < start); if (_negate) { _start = finish; _finish = start; } else { _start = start; _finish = finish; } int _diff = 0; while (_start.AddMonths(1) < _finish) { _diff++; _start = _start.AddMonths(1); } if (_negate) { _diff = _diff * (-1); } return _diff; } ///  /// returns the integer number of days between start and finish ///  /// start DateTime /// finish DateTime ///  public static int DayDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalDays; } ///  /// returns the integer number of hours between start and finish ///  /// start DateTime /// finish DateTime ///  public static int HourDiff(DateTime start, DateTime finish) { var _diff = finish - start; return(int)_diff.TotalHours; } ///  /// returns the integer number of minutes between start and finish ///  /// start DateTime /// finish DateTime ///  public static int MinuteDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalMinutes; } ///  /// returns the integer number of seconds between start and finish ///  /// start DateTime /// finish DateTime ///  public static int SecondDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalSeconds; } ///  /// returns the integer number of milliseconds between start and finish ///  /// start DateTime /// finish DateTime ///  public static int MilliSecondDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalMilliseconds; } ///  /// returns the integer remaining number of months between two DateTimes /// after the year difference has been removed ///  /// start DateTime /// finish DateTime ///  public static int MonthPartDiff(DateTime start, DateTime finish) { return MonthDiff(start.AddYears(YearDiff(start, finish)), finish); } ///  /// returns the integer remaining number of days between two DateTimes /// after the year difference and the month difference has been removed ///  ///  ///  ///  public static int DayPartDiff(DateTime start, DateTime finish) { return DayDiff(start.AddMonths(MonthDiff(start, finish)), finish); } ///  /// returns the integer remaining number of hours between two DateTimes /// after the year, month and day difference has been removed ///  ///  ///  ///  public static int HourPartDiff(DateTime start, DateTime finish) { return (finish-start).Hours; } ///  /// returns the integer remaining number of minutes between two DateTimes /// after the year, month, day and hour difference has been removed ///  ///  ///  ///  public static int MinutePartDiff(DateTime start, DateTime finish) { return (finish-start).Minutes; } ///  /// returns the integer remaining number of seconds between two DateTimes /// after the year, month, day, hour and minute difference has been removed ///  ///  ///  ///  public static int SecondPartDiff(DateTime start, DateTime finish) { return (finish - start).Seconds; } ///  /// returns the integer remaining number of milliseconds between two DateTimes /// after the year, month, day, hour, minute and second difference has been removed ///  ///  ///  ///  public static int MilliSecondPartDiff(DateTime start, DateTime finish) { return (finish - start).Milliseconds; } } 

所以你可以这样称呼它:

 var finish = DateTime.Now; var start = new DateTime(1967, 7, 3); var years = DateCalcs.YearDiff(start, finish); Console.WriteLine ("Age in years: {0}", years); var months = DateCalcs.MonthDiff(start, finish); Console.WriteLine("Age in months: {0}", months); var days = DateCalcs.DayDiff(start, finish); Console.WriteLine("Age in days: {0}", days); var hours = DateCalcs.HourDiff(start, finish); Console.WriteLine("Age in hours: {0}", hours); var minutes = DateCalcs.MinuteDiff(start, finish); Console.WriteLine("Age in minutes: {0}", minutes); var seconds = DateCalcs.SecondDiff(start, finish); Console.WriteLine("Age in seconds: {0}", seconds); var milliSeconds = DateCalcs.MilliSecondDiff(start, finish); Console.WriteLine("Age in milliseconds: {0}", milliSeconds); var AgeString = string.Format("{0}yr, {1}mo, {2}d, {3}h, {4}m, {5}s, {6}ms", DateCalcs.YearDiff(start, finish), DateCalcs.MonthPartDiff(start, finish), DateCalcs.DayPartDiff(start, finish), DateCalcs.HourPartDiff(start, finish), DateCalcs.MinutePartDiff(start, finish), DateCalcs.SecondPartDiff(start, finish), DateCalcs.MilliSecondPartDiff(start, finish) ); Console.WriteLine("Or {0}", AgeString); 

刚刚回来了

 Age in years: 46 Age in months: 560 Age in days: 17073 Age in hours: 409771 Age in minutes: 24586290 Age in seconds: 1475177401 Age in milliseconds: -2147483648 Or 46yr, 8mo, 28d, 19h, 30m, 1s, 792ms