使用 C# 的年份日期差异 [重复]
Posted
技术标签:
【中文标题】使用 C# 的年份日期差异 [重复]【英文标题】:Date difference in years using C# [duplicate] 【发布时间】:2011-05-06 20:32:39 【问题描述】:如何计算两个日期之间的年差?
例如:(Datetime.Now.Today() - 11/03/2007)
以年为单位。
【问题讨论】:
发现骗子的功劳归于 Doggett。 您标记为答案的代码实际上是不正确的。它可能会返回不正确的结果 【参考方案1】:我编写了一个实现,可以正确处理相隔一年的日期。
但是,与其他算法不同,它不能优雅地处理负时间跨度。它也不使用自己的日期算法,而是依赖标准库。
废话不多说,代码如下:
DateTime zeroTime = new DateTime(1, 1, 1);
DateTime a = new DateTime(2007, 1, 1);
DateTime b = new DateTime(2008, 1, 1);
TimeSpan span = b - a;
// Because we start at year 1 for the Gregorian
// calendar, we must subtract a year here.
int years = (zeroTime + span).Year - 1;
// 1, where my other algorithm resulted in 0.
Console.WriteLine("Yrs elapsed: " + years);
【讨论】:
平均处理闰年,但每年最多有 18 个小时会关闭一个。 使用此方法,2007 年 1 月 1 日和 2008 年 1 月 1 日之间的差值为 0 年。直观地说,应该是 1 年。 @Downvoter 请解释一下?我刚刚对我的帖子进行了重大更新,虽然晚了 3 年,但它并没有降低编辑所获得的质量。 今天(12 月 31 日)这对我们不利。当将 12/31 日期与 1/1 进行比较时,加法数学会导致一个偏离一天的问题。我们首先从跨度中减去一天来修复它。 这会给你正确答案的概率是相当高的,但是,如果你想让它 100% 的工作,这个答案是错误的。因为闰年。开始日期很重要!【参考方案2】:用途:
int Years(DateTime start, DateTime end)
return (end.Year - start.Year - 1) +
(((end.Month > start.Month) ||
((end.Month == start.Month) && (end.Day >= start.Day))) ? 1 : 0);
【讨论】:
这表示 2008-Nov-02 比 2007-Nov-03 晚一年,大多数人会说它短了一天。 你是对的。我已经更新了我的代码以严格关闭 Year、Month 和 Day 属性。它现在变得有点难看,但适用于闰年。 我知道这是一个旧的答案,但只是想补充一点,这可以通过比较 DayOfYear 属性而不是同时比较 Month 和 Year 来简化。 @Tarec - 我的第一个版本使用了DayOfYear
属性...但是由于@BenVoigt 的评论,我改变了一些事情。【参考方案3】:
我们必须编写检查代码以确定两个日期(开始日期和结束日期)之间的差异是否大于 2 年。
感谢上面的提示,完成如下:
DateTime StartDate = Convert.ToDateTime("01/01/2012");
DateTime EndDate = Convert.ToDateTime("01/01/2014");
DateTime TwoYears = StartDate.AddYears(2);
if EndDate > TwoYears .....
【讨论】:
也许不是这个问题的实际解决方案,但它解决了我的问题,所以赞成:) 短版:If (Birthday.AddYears(18) > DateTime.UtcNow.Date) //under 18 而不是做 DateTime TwoYears = StartDate.AddYears(2);如果您从中减去 1 天: DateTime TwoYears = StartDate.AddYears(2).AddDays(-1);你会得到更准确的答案...我不知道这取决于要求。【参考方案4】:如果您因为一些琐碎的原因需要它来了解某人的年龄,那么 Timespan 是可以的,但如果您需要计算退休金、长期存款或其他任何出于财务、科学或法律目的的东西,那么恐怕 Timespan 将不准确足够了,因为 Timespan 假设每年都有相同的天数、相同的小时数和相同的秒数)。
实际上,某些年份的长度会有所不同(出于此答案范围之外的不同原因)。为了绕过时间跨度的限制,您可以模仿 Excel 的功能:
public int GetDifferenceInYears(DateTime startDate, DateTime endDate)
//Excel documentation says "COMPLETE calendar years in between dates"
int years = endDate.Year - startDate.Year;
if (startDate.Month == endDate.Month &&// if the start month and the end month are the same
endDate.Day < startDate.Day// AND the end day is less than the start day
|| endDate.Month < startDate.Month)// OR if the end month is less than the start month
years--;
return years;
【讨论】:
我一直在使用这个旧代码,但我只是被闰年咬了。客户报告将 3 年的差异显示为两年 - 结果是 2 月 29 日 -> 2 月 28 日被四舍五入,比人类实际预期的要少一年。【参考方案5】:var totalYears =
(DateTime.Today - new DateTime(2007, 03, 11)).TotalDays
/ 365.2425;
Wikipedia/Leap_year 的平均天数。
【讨论】:
平均正确。但并非总是如此。 @Mick 您能否解释一下在什么具体情况下会出错?谢谢。 @NamLe 如果是闰年,一年中的天数是 365 天或 366 天。它永远不是 365.2425 天。因此,这个公式只会近似正确。 这并不完全正确。这个“近似值”实际上是一年中的确切天数(这就是为什么我们有闰年 - 以补偿这一天的四分之一)并且通过适当的四舍五入,你总是会得到正确的年数。 【参考方案6】:int Age = new DateTime((DateTime.Now - BirthDateTime).Ticks).Year;
计算经过的岁数(年龄),结果为负一。
var timeSpan = DateTime.Now - birthDateTime;
int age = new DateTime(timeSpan.Ticks).Year - 1;
【讨论】:
它实际上是不正确的,因为它正在四舍五入。我今年 40 岁,报告 41 岁。再过 3 周我就不是 41 岁了。 另外它没有正确考虑闰年【参考方案7】:这是一个巧妙的技巧,可以让系统自动处理闰年。它为所有日期组合提供了准确的答案。
DateTime dt1 = new DateTime(1987, 9, 23, 13, 12, 12, 0);
DateTime dt2 = new DateTime(2007, 6, 15, 16, 25, 46, 0);
DateTime tmp = dt1;
int years = -1;
while (tmp < dt2)
years++;
tmp = tmp.AddYears(1);
Console.WriteLine("0", years);
【讨论】:
这是一个好主意,但不是在循环中更改 tmp 日期,而是应该增加年数。如果您预计 2012 年 2 月 29 日 - 2016 年 2 月 29 日返回 4,这将正常工作。【参考方案8】:不清楚你想如何处理小数年,但可能是这样的:
DateTime now = DateTime.Now;
DateTime origin = new DateTime(2007, 11, 3);
int calendar_years = now.Year - origin.Year;
int whole_years = calendar_years - ((now.AddYears(-calendar_years) >= origin)? 0: 1);
int another_method = calendar_years - ((now.Month - origin.Month) * 32 >= origin.Day - now.Day)? 0: 1);
【讨论】:
根据这种方法,2/28/2009 是 2/29/2008 之后的 1 年,而看起来应该比 1 年略短。我想闰年的处理总是会有点不满意。 @o. nate:修复了,也许(使用在 Doggett 发现的另一个问题上发现的技巧)。我认为像 Dana 的解决方案可能需要在两个方向上修复闰日情况。【参考方案9】:我实现了一个扩展方法来获取两个日期之间的年数,以整月四舍五入。
/// <summary>
/// Gets the total number of years between two dates, rounded to whole months.
/// Examples:
/// 2011-12-14, 2012-12-15 returns 1.
/// 2011-12-14, 2012-12-14 returns 1.
/// 2011-12-14, 2012-12-13 returns 0,9167.
/// </summary>
/// <param name="start">
/// Stardate of time period
/// </param>
/// <param name="end">
/// Enddate of time period
/// </param>
/// <returns>
/// Total Years between the two days
/// </returns>
public static double DifferenceTotalYears(this DateTime start, DateTime end)
// Get difference in total months.
int months = ((end.Year - start.Year) * 12) + (end.Month - start.Month);
// substract 1 month if end month is not completed
if (end.Day < start.Day)
months--;
double totalyears = months / 12d;
return totalyears;
【讨论】:
此解决方案将每个月视为一年的 1/12。它会倾斜,因为有些月份的大小不是这样的 并不总是返回正确的结果【参考方案10】: public string GetAgeText(DateTime birthDate)
const double ApproxDaysPerMonth = 30.4375;
const double ApproxDaysPerYear = 365.25;
int iDays = (DateTime.Now - birthDate).Days;
int iYear = (int)(iDays / ApproxDaysPerYear);
iDays -= (int)(iYear * ApproxDaysPerYear);
int iMonths = (int)(iDays / ApproxDaysPerMonth);
iDays -= (int)(iMonths * ApproxDaysPerMonth);
return string.Format("0 år, 1 måneder, 2 dage", iYear, iMonths, iDays);
【讨论】:
【参考方案11】:我在 TimeSpan for years, months and days 找到了这个:
DateTime target_dob = THE_DOB;
DateTime true_age = DateTime.MinValue + ((TimeSpan)(DateTime.Now - target_dob )); // Minimum value as 1/1/1
int yr = true_age.Year - 1;
【讨论】:
【参考方案12】:如果您要处理月份和年份,您需要知道每个月有多少天以及哪些年份是闰年。
输入Gregorian Calendar(和其他特定于文化的Calendar 实现)。
虽然 Calendar 没有提供直接计算两个时间点之间差异的方法,但它确实有诸如
之类的方法DateTime AddWeeks(DateTime time, int weeks)
DateTime AddMonths(DateTime time, int months)
DateTime AddYears(DateTime time, int years)
【讨论】:
【参考方案13】:DateTime musteriDogum = new DateTime(dogumYil, dogumAy, dogumGun);
int additionalDays = ((DateTime.Now.Year - dogumYil) / 4); //Count of the years with 366 days
int extraDays = additionalDays + ((DateTime.Now.Year % 4 == 0 || musteriDogum.Year % 4 == 0) ? 1 : 0); //We add 1 if this year or year inserted has 366 days
int yearsOld = ((DateTime.Now - musteriDogum).Days - extraDays ) / 365; // Now we extract these extra days from total days and we can divide to 365
【讨论】:
【参考方案14】:完美运行:
internal static int GetDifferenceInYears(DateTime startDate)
int finalResult = 0;
const int DaysInYear = 365;
DateTime endDate = DateTime.Now;
TimeSpan timeSpan = endDate - startDate;
if (timeSpan.TotalDays > 365)
finalResult = (int)Math.Round((timeSpan.TotalDays / DaysInYear), MidpointRounding.ToEven);
return finalResult;
【讨论】:
【参考方案15】:简单的解决方案:
public int getYearDiff(DateTime startDate, DateTime endDate)
int y = Year(endDate) - Year(startDate);
int startMonth = Month(startDate);
int endMonth = Month(endDate);
if (endMonth < startMonth)
return y - 1;
if (endMonth > startMonth)
return y;
return (Day(endDate) < Day(startDate) ? y - 1 : y);
【讨论】:
【参考方案16】:这是计算年月差的最佳代码:
DateTime firstDate = DateTime.Parse("1/31/2019");
DateTime secondDate = DateTime.Parse("2/1/2016");
int totalYears = firstDate.Year - secondDate.Year;
int totalMonths = 0;
if (firstDate.Month > secondDate.Month)
totalMonths = firstDate.Month - secondDate.Month;
else if (firstDate.Month < secondDate.Month)
totalYears -= 1;
int monthDifference = secondDate.Month - firstDate.Month;
totalMonths = 12 - monthDifference;
if ((firstDate.Day - secondDate.Day) == 30)
totalMonths += 1;
if (totalMonths % 12 == 0)
totalYears += 1;
totalMonths = 0;
【讨论】:
为什么这是投注码?看起来相当复杂【参考方案17】:也许这有助于回答以下问题:给定年份的天数,
new DateTime(anyDate.Year, 12, 31).DayOfYear //will include leap years too
关于DateTime.DayOfYear Property。
【讨论】:
【参考方案18】:以下内容基于 Dana 的简单代码,该代码在大多数情况下都能产生正确答案。但它没有考虑到日期之间不到一年。所以这是我用来产生一致结果的代码:
public static int DateDiffYears(DateTime startDate, DateTime endDate)
var yr = endDate.Year - startDate.Year - 1 +
(endDate.Month >= startDate.Month && endDate.Day >= startDate.Day ? 1 : 0);
return yr < 0 ? 0 : yr;
【讨论】:
这也展示了@davomcdavo 回答的闰年行为 你不能用endDate.Month >= startDate.Month && endDate.Day >= startDate.Day
替换(end.Month > start.Month) || ((end.Month == start.Month) && (end.Day >= start.Day))
【参考方案19】:
希望下面的链接对你有帮助
MSDN - DateTime.Subtract.Method (DateTime)
那里甚至还有 C# 的示例。只需单击 C# 语言选项卡即可。
祝你好运
【讨论】:
以上是关于使用 C# 的年份日期差异 [重复]的主要内容,如果未能解决你的问题,请参考以下文章