DateTime difference returing correct no of months and or even years?
是否有任何内置函数,我如何才能以比仅天数更好的方式获得日期时间对象之间的差异?我的意思是1个月23天。由于每个月的天数、闰年等不同,我觉得很难计算。谢谢
看看野田时间。一般来说,它还没有准备好生产,但是相关的位可以很好地满足您当前的需求:)
注意,
在野田佳彦时期,你需要一个
请注意,日期/时间算术很难…在某些情况下,"正确的答案"根本不明显。
月可以是28天、29天、30天或31天;年可以是365天或366天。因此,当您试图计算月份和年份的完整时间单位时,会出现问题,因此如果您可以假设一些东西,那么您可以检查这个问题。
简单的减法可以做到:
1 2 3 4 | int months = departure.Months - arrival.Months; int years = departure.Years - arrival.Years; //in case multiple years have elapsed . int months += years * 12; |
很明显,当涉及到天数时,你需要做一些数学计算,如果你不关心精度,如果日差是负数,你需要从月份中减去一个。
然后您可以使用时间跨度来获得更高的精度,也就是经过的时间。
1 2 3 4 5 6 7 8 9 | //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 |
这是我刚写的一些代码,用来计算年、月和日的差异。它在公共领域。
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 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<earlier) throw new ArgumentException("later is earlier than 'earlier'."); bool isleapday=(earlier.Month==2 && earlier.Day==29); DateTime tmp=isleapday ? new DateTime(earlier.Year,2,28) : earlier; while(true){ try { tmp=tmp.AddYears(1); if(isleapday && DateTime.IsLeapYear(tmp.Year)) tmp=new DateTime(tmp.Year,2,29); } catch(ArgumentOutOfRangeException){ break; } if(tmp<=later){ years++; earlier=tmp; } else { break; } } // Add months tmp=earlier; while(true){ try { tmp=tmp.AddMonths(1); if(isleapday && tmp.Day!=29 && tmp.Month!=2) tmp=new DateTime(tmp.Year,tmp.Month,29); } catch(ArgumentOutOfRangeException){ break; } if(tmp<=later){ months++; earlier=tmp; } else { break; } } tmp=earlier; while(true){ try { tmp=tmp.AddDays(1); } catch(ArgumentOutOfRangeException){ break; } if(tmp<=later){ days++; earlier=tmp; } else { break; } } } } |
例子:
1 2 3 4 |
这类问题对于日历日期来说非常难指定。看看这里如何计算一个人的年龄(以年为单位)。
以C为单位计算年龄#
复杂性来自边缘情况。显然,1月31日是12月31日之后的一个月。但是,2月28日是1月31日之后的一个月吗?在正常年份?在闰年?在编写代码之前,您需要指定这些类型的案例。
生日算法使用向下取整和递增策略。考虑到你对上一段中的问题的回答,这同样适用于月份差异。
这是一个类,它允许您查询一对日期时间差的各种属性。我刚刚把它搅了起来,并将它发布到公共领域。照你的意愿去做,但要自担风险地使用它。
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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | public static class DateCalcs { /// <summary> /// returns the integer number of years between start and finish /// </summary> /// <param name="start">Start DateTime</param> /// <param name="finish">FinishDateTime</param> /// <returns></returns> 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; } /// <summary> /// returns the integer number of months between start and finish /// </summary> /// <param name="start">Start DateTime</param> /// <param name="finish">Finish DateTime</param> /// <returns></returns> 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; } /// <summary> /// returns the integer number of days between start and finish /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int DayDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalDays; } /// <summary> /// returns the integer number of hours between start and finish /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int HourDiff(DateTime start, DateTime finish) { var _diff = finish - start; return(int)_diff.TotalHours; } /// <summary> /// returns the integer number of minutes between start and finish /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int MinuteDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalMinutes; } /// <summary> /// returns the integer number of seconds between start and finish /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int SecondDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalSeconds; } /// <summary> /// returns the integer number of milliseconds between start and finish /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int MilliSecondDiff(DateTime start, DateTime finish) { var _diff = finish - start; return (int)_diff.TotalMilliseconds; } /// <summary> /// returns the integer remaining number of months between two DateTimes /// after the year difference has been removed /// </summary> /// <param name="start">start DateTime</param> /// <param name="finish">finish DateTime</param> /// <returns></returns> public static int MonthPartDiff(DateTime start, DateTime finish) { return MonthDiff(start.AddYears(YearDiff(start, finish)), finish); } /// <summary> /// returns the integer remaining number of days between two DateTimes /// after the year difference and the month difference has been removed /// </summary> /// <param name="start"></param> /// <param name="finish"></param> /// <returns></returns> public static int DayPartDiff(DateTime start, DateTime finish) { return DayDiff(start.AddMonths(MonthDiff(start, finish)), finish); } /// <summary> /// returns the integer remaining number of hours between two DateTimes /// after the year, month and day difference has been removed /// </summary> /// <param name="start"></param> /// <param name="finish"></param> /// <returns></returns> public static int HourPartDiff(DateTime start, DateTime finish) { return (finish-start).Hours; } /// <summary> /// returns the integer remaining number of minutes between two DateTimes /// after the year, month, day and hour difference has been removed /// </summary> /// <param name="start"></param> /// <param name="finish"></param> /// <returns></returns> public static int MinutePartDiff(DateTime start, DateTime finish) { return (finish-start).Minutes; } /// <summary> /// returns the integer remaining number of seconds between two DateTimes /// after the year, month, day, hour and minute difference has been removed /// </summary> /// <param name="start"></param> /// <param name="finish"></param> /// <returns></returns> public static int SecondPartDiff(DateTime start, DateTime finish) { return (finish - start).Seconds; } /// <summary> /// returns the integer remaining number of milliseconds between two DateTimes /// after the year, month, day, hour, minute and second difference has been removed /// </summary> /// <param name="start"></param> /// <param name="finish"></param> /// <returns></returns> public static int MilliSecondPartDiff(DateTime start, DateTime finish) { return (finish - start).Milliseconds; } } |
所以你可以这样称呼它:
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 | 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); |
刚刚回来的
1 2 3 4 5 6 7 8 | 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 |
试试这个
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 | 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"); } |
对我来说很好
可以使用.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 | // ---------------------------------------------------------------------- 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 |