c# date comparison returning a DateTime object
Given a DateTime object (last purchase) can I compare against DateTime.Now to return a new DateTime object that contains, years, months, days, hours and seconds?
I can compare dates and return the number of years h开发者_开发问答owever, I need all details down to the second.
Any help or examples would be appreciated
You don't want to have a new DateTime
object. What you want to have is a TimeSpan
. And that's what you get if you subtract DateTime
instances:
TimeSpan difference = DateTime.Now - yourDate
No, you can't, because a DateTime
represents an absolute point in time, not a span of time. The correct object to use for the difference is TimeSpan
. It has properties for all the relevant time units. You can get one by just subtracting two DateTime
s:
TimeSpan ts = DateTime.Now - purchaseDate;
You can use the TimeSpan to compare two dates. Have a look at
DateTime date1 = new DateTime(2010, 1, 1, 8, 0, 15);
DateTime date2 = new DateTime(2010, 8, 18, 13, 30, 30);
// Calculate the interval between the two dates.
TimeSpan interval = date2 - date1;
Years and months have to be calculated through custom coding as month is a variable unit of measure but since TimeSpan tell you the days you can calculate months and years yourself.
Have a look at this post.
Have a look at this forum.
Hope this help.
TimeSpan is the correct way to handle this, however, if you don't want to do the conversion of months/years yourself, you can always use some recursive method to subtract years until you get to the correct year, months until you get to the correct month, days until you get to the correct day, etc. It would suck and be ugly, though.
Also, you'd need a custom object that would hold the data for you.
A rough cut would be something like
DateTime original = [Whatever]
DateTime compare = [Whatever]
DateTimeDiff difference = GetDifference(original, compare)
GetDifference(DateTime original, DateTime compare)
{
DateTimeDiff difference = new DateTimeDifference
while(!original.Equals(compare) && original.Year >= compare.Year)
{
original.AddYears(-1);
difference.Years++;
}
<snip... //more code to do the same thing for months, days, hours, etc.)
}
Like I said, it would suck and be ugly, but you could do it.
This library includes the class DateDiff with support of Year and Months:
// ----------------------------------------------------------------------
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
} // DateDiffSample
If you want years and months you have to write your own code. It's actually tricky to write this code with an output which is 100% correct due to the different leapyear issues.
Here are a couple of tricky special cases (Note 2012 is a leap year, 2011 isn't):
- Between February 28th 2010 and February 28th 2011 - it is 1y, 0m, 0d
- Between February 28th 2011 and February 28th 2012 - it is 1y, 11m, 28d
- Between February 28th 2011 and February 29th 2012 - it is 1y, 0m, 0d
- Between February 29th 2012 and February 28th 2013 - it is 1y, 0m, 0d
- Between February 10th 2011 and March 9th 2011 - it is 0y, 0m, 27d
- Between February 10th 2012 and March 9th 2012 - it is 0y, 0m, 28d
I think you need to implement something like AllenG's algorithm with a few modifications
- You need to start with the earliest datetime (datetime1). Make sure that it is earliest.
Loop until datetime1.AddYears(1) compares as greater than or equal to your latest datetime (datetime2). Make sure to compare the entire datetimes and not just the year property of starttime and endttime.
- Increment a year counter on each iteration.
- actually add a year to your datetime1 copy.
Start with the datetime1 copy (to which you have added years in step 2)
- Loop until datetime1.AddMonths(1) compares as greater than or equal to your latest datetime (datetime2). Again: Make sure you compare the entire datetimes and not just the month component.
- Increment a month counter on each iteration.
- actually add a month to your datetime1 copy.
- etc. etc
This algorithm ensures that you are calculating your years, months, days, hours, minutes and seconds differences using the right excerpt of the underlying calendar.
I think you need to combine the TimeSpan
and some custom calculations. This, because you would like the years and months, which have a variable length. In addition you also want the number of hours, minutes and seconds.
I think this approach would serve your needs:
var date1 = new DateTime(2010, 1, 1, 8, 0, 15);
var date2 = new DateTime(2007, 8, 18, 13, 30, 30);
var differenceYears = date1.Year - date2.Year;
var tempDate = date2.AddYears(differenceYears);
var differenceMonths = date1.Month - tempDate.Month;
if (differenceMonths < 0)
{
differenceMonths += 12;
differenceYears--;
}
tempDate = date2.AddYears(differenceYears).AddMonths(differenceMonths);
var additionalTimeSpan = date1 - tempDate;
var differenceDays = additionalTimeSpan.Days;
var differenceHours = additionalTimeSpan.Hours;
var differenceMinutes = additionalTimeSpan.Minutes;
var differenceSeconds = additionalTimeSpan.Seconds;
精彩评论