Rau*_*auf 306 .net c# vb.net date
如何计算C#中两个日期之间的月份差异?
DateDiff()在C#中是否有相当于VB的方法.我需要找出两个相隔数年的日期之间的差异.文档说我可以使用TimeSpan:
TimeSpan ts = date1 - date2;
Run Code Online (Sandbox Code Playgroud)
但这给了我几天的数据.我不想将这个数字除以30,因为不是每个月都是30天,而且因为两个操作数值彼此相距很远,我担心除以30可能会给我一个错误的值.
有什么建议?
Ada*_*lph 434
假设月份的日期无关紧要(即2011.1.1和2010.12.31之间的差异为1),date1> date2给出正值,date2> date1为负值
((date1.Year - date2.Year) * 12) + date1.Month - date2.Month
Run Code Online (Sandbox Code Playgroud)
或者,假设您希望两个日期之间的"平均月份"大致相同,则以下内容应适用于所有但非常大的日期差异.
date1.Subtract(date2).Days / (365.25 / 12)
Run Code Online (Sandbox Code Playgroud)
请注意,如果您要使用后一种解决方案,那么您的单元测试应说明您的应用程序设计使用的最宽日期范围,并相应地验证计算结果.
更新(感谢Gary)
如果使用"平均月份"方法,则用于"每年平均天数"的稍微准确的数字是365.2425.
Kir*_*oll 199
这是一个全面的解决方案,返回a DateTimeSpan,类似于a TimeSpan,除了它包括除时间组件之外的所有日期组件.
用法:
void Main()
{
DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
var dateSpan = DateTimeSpan.CompareDates(compareTo, now);
Console.WriteLine("Years: " + dateSpan.Years);
Console.WriteLine("Months: " + dateSpan.Months);
Console.WriteLine("Days: " + dateSpan.Days);
Console.WriteLine("Hours: " + dateSpan.Hours);
Console.WriteLine("Minutes: " + dateSpan.Minutes);
Console.WriteLine("Seconds: " + dateSpan.Seconds);
Console.WriteLine("Milliseconds: " + dateSpan.Milliseconds);
}
Run Code Online (Sandbox Code Playgroud)
输出:
年:1
个月:5
天:27
小时:1
分钟:36
秒:50
毫秒:0
为方便起见,我将逻辑集中到DateTimeSpan结构中,但您可以将方法移动到CompareDates您认为合适的位置.另请注意,哪一个日期先于另一个日期并不重要.
public struct DateTimeSpan
{
public int Years { get; }
public int Months { get; }
public int Days { get; }
public int Hours { get; }
public int Minutes { get; }
public int Seconds { get; }
public int Milliseconds { get; }
public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
Years = years;
Months = months;
Days = days;
Hours = hours;
Minutes = minutes;
Seconds = seconds;
Milliseconds = milliseconds;
}
enum Phase { Years, Months, Days, Done }
public static DateTimeSpan CompareDates(DateTime date1, DateTime date2)
{
if (date2 < date1)
{
var sub = date1;
date1 = date2;
date2 = sub;
}
DateTime current = date1;
int years = 0;
int months = 0;
int days = 0;
Phase phase = Phase.Years;
DateTimeSpan span = new DateTimeSpan();
int officialDay = current.Day;
while (phase != Phase.Done)
{
switch (phase)
{
case Phase.Years:
if (current.AddYears(years + 1) > date2)
{
phase = Phase.Months;
current = current.AddYears(years);
}
else
{
years++;
}
break;
case Phase.Months:
if (current.AddMonths(months + 1) > date2)
{
phase = Phase.Days;
current = current.AddMonths(months);
if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month))
current = current.AddDays(officialDay - current.Day);
}
else
{
months++;
}
break;
case Phase.Days:
if (current.AddDays(days + 1) > date2)
{
current = current.AddDays(days);
var timespan = date2 - current;
span = new DateTimeSpan(years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds);
phase = Phase.Done;
}
else
{
days++;
}
break;
}
}
return span;
}
}
Run Code Online (Sandbox Code Playgroud)
Mon*_*ong 35
你可以做到
if ( date1.AddMonths(x) > date2 )
Run Code Online (Sandbox Code Playgroud)
Gui*_*e86 32
如果你想要确切的完整月数,总是积极的(2000-01-15,2000-02-14返回0),考虑整个月是你到达下个月的同一天(类似于年龄计算)
public static int GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
return monthDiff - 1;
}
else
{
return monthDiff;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑原因:旧代码在某些情况下不正确,例如:
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
Test cases I used to test the function:
var tests = new[]
{
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 2), Result = 0 },
new { From = new DateTime(1900, 1, 2), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 2, 1), Result = 1 },
new { From = new DateTime(1900, 2, 1), To = new DateTime(1900, 1, 1), Result = 1 },
new { From = new DateTime(1900, 1, 31), To = new DateTime(1900, 2, 1), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 9, 30), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 10, 1), Result = 1 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1901, 1, 1), Result = 12 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1911, 1, 1), Result = 132 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
};
Run Code Online (Sandbox Code Playgroud)
Che*_*hen 22
我通过MSDN在VB.NET中检查了这个方法的用法,似乎它有很多用法.C#中没有这样的内置方法.(即使这不是一个好主意)你可以用C#调用VB.
Microsoft.VisualBasic.dll到您的项目作为参考Microsoft.VisualBasic.DateAndTime.DateDiff
在你的代码Chi*_*rag 10
无论日期如何,要在几个月内(包括开始和结束)获得差异:
DateTime start = new DateTime(2013, 1, 1);
DateTime end = new DateTime(2014, 2, 1);
var diffMonths = (end.Month + end.Year * 12) - (start.Month + start.Year * 12);
Run Code Online (Sandbox Code Playgroud)
我只需要一些简单的东西来满足例如只输入月份/年份的就业日期,因此需要不同的年份和月份.这就是我使用的,这里仅用于实用性
public static YearsMonths YearMonthDiff(DateTime startDate, DateTime endDate) {
int monthDiff = ((endDate.Year * 12) + endDate.Month) - ((startDate.Year * 12) + startDate.Month) + 1;
int years = (int)Math.Floor((decimal) (monthDiff / 12));
int months = monthDiff % 12;
return new YearsMonths {
TotalMonths = monthDiff,
Years = years,
Months = months
};
}
Run Code Online (Sandbox Code Playgroud)
使用Noda时间:
LocalDate start = new LocalDate(2013, 1, 5);
LocalDate end = new LocalDate(2014, 6, 1);
Period period = Period.Between(start, end, PeriodUnits.Months);
Console.WriteLine(period.Months); // 16
Run Code Online (Sandbox Code Playgroud)
以下是我为获得准确的月份差异所做的贡献:
namespace System
{
public static class DateTimeExtensions
{
public static Int32 DiffMonths( this DateTime start, DateTime end )
{
Int32 months = 0;
DateTime tmp = start;
while ( tmp < end )
{
months++;
tmp = tmp.AddMonths( 1 );
}
return months;
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Int32 months = DateTime.Now.DiffMonths( DateTime.Now.AddYears( 5 ) );
Run Code Online (Sandbox Code Playgroud)
您可以创建另一个名为 DiffYears 的方法,并应用与上面完全相同的逻辑,并在 while 循环中应用 AddYears 而不是 AddMonths。