曾经面试的时候被问到写一段函数,实现不用系统已经提供的方法计算两个日期的差值。当时时间很短,脑袋很糊涂,今天细想了一下,实现如下:
首先定义了一个MyDate类:
class Mydate
{
private int year;
private int month;
private int day;
public int Year
{
get { return year; }
}
public int Month
{
get { return month; }
}
public int Day
{
get { return day; }
}
public Mydate(int year, int month, int day)
{
this.year = year;
this.month = month;
this.day = day;
}
}
{
private int year;
private int month;
private int day;
public int Year
{
get { return year; }
}
public int Month
{
get { return month; }
}
public int Day
{
get { return day; }
}
public Mydate(int year, int month, int day)
{
this.year = year;
this.month = month;
this.day = day;
}
}
接下来我取较小的日期的年和一月一号组成一个参照的日期,分别计算两个日期和它的天数的差值,最后这两个值相减就是结果了,我觉得这样比较简单:
Code
我们可以使用系统提供的类来验证,例如:
DateTime
dt1 = new DateTime(1999, 9, 10);
DateTime dt2 = new DateTime(2005, 2, 17);
int diff2 = ((TimeSpan)(dt1.Subtract(dt2))).Days;
改进一下:
View Code
class MyTest
{
private static readonly int[] _leapdays = new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static readonly int[] _normaldays = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public static int GetDiff2(DateTime d1, DateTime d2)
{
if (d1.Year == d2.Year && d1.Month == d2.Month)
return Math.Abs(d1.Day - d2.Day);
// make sure d1 < d2.
if ((d1.Year > d2.Year) || (d1.Year == d2.Year && d1.Month > d2.Month))
{
var temp = d2;
d2 = d1;
d1 = temp;
}
int sum1 = 0;
int sum2 = 0;
for (int i = 1; i < d1.Month; i++)
sum1 += GetDaysofMonth(d1.Year, i);
sum1 += d1.Day;
for (int i = 1; i < d2.Month; i++)
sum2 += GetDaysofMonth(d2.Year, i);
sum2 += d2.Day;
for (int i = d1.Year; i < d2.Year; i++)
sum2 += DateTime.IsLeapYear(i) ? 366 : 365;
return sum2 - sum1;
}
/// <summary>
/// Gets days of a specified year, month.
/// </summary>
/// <param name="year"></param>
/// <param name="month">1-based, from 1 to 12</param>
/// <returns></returns>
public static int GetDaysofMonth(int year, int month)
{
if (DateTime.IsLeapYear(year))
return _leapdays[month - 1];
else
return _normaldays[month - 1];
}
}
以下是测试代码:
View Code
private void Test()
{
Random r = new Random();
Debug.WriteLine("date1\tdate2\tdiffmytest\tdiffsystem");
for (int i = 0; i < 10000; i++)
{
var y1 = r.Next(1957, 2012);
var m1 = r.Next(1, 12);
var d1 = r.Next(1, MyTest.GetDaysofMonth(y1, m1));
var y2 = r.Next(1957, 2012);
var m2 = r.Next(1, 12);
var d2 = r.Next(1, MyTest.GetDaysofMonth(y2, m2));
var date1 = new DateTime(y1, m1, d1);
var date2 = new DateTime(y2, m2, d2);
var v1 = MyTest.GetDiff2(date1, date2);
var v2 = Math.Abs(date1.Subtract(date2).Days);
Debug.WriteLine(date1.ToShortDateString() + "\t" + date2.ToShortDateString() + "\t" + v1 + "\t" + v2);
if (v1 != v2)
{
MessageBox.Show("failed" + date1.ToShortDateString() + "\t" + date2.ToShortDateString() + "\t" + v1 + "\t" + v2);
}
}
}