日期返回正确的月数和年数的时差
本文关键字:时差 返回 日期 | 更新日期: 2023-09-27 18:00:43
是否有任何内置函数?如何以比天数更好的方式获得tho-DateTime对象之间的差异?我的意思是大约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日之后的一个月。但是,2月28日是1月31日之后的一个月吗?在正常年份?闰年?在编写代码之前,您需要指定这些类型的案例。
生日算法采用四舍五入和递增策略。考虑到你对上一段中问题的回答,这也适用于月份差异。
以下是我刚刚编写的一些代码,用于计算年、月和天的差异。它在公共领域。
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;
}
}
}
}
示例:
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
您可以将时间段库的DateDiff类用于。NET:
// ----------------------------------------------------------------------
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
{
/// <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;
}
}
所以你可以这样称呼它:
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