DateTime range

  • Thread starter Thread starter shapper
  • Start date Start date
S

shapper

Hello,

I have two nullable DateTime: begin and end.
I need to find the range, in month, between both variables.

If for some reason, for example begin is null, it is not possible to
calculate the range then I want to define the range as 1 month.

How can I do this?

Thanks,
Miguel
 
shapper said:
I have two nullable DateTime: begin and end.
I need to find the range, in month, between both variables.

If for some reason, for example begin is null, it is not possible to
calculate the range then I want to define the range as 1 month.

How can I do this?

I don't think there are any magic.

if(dt1 != null && dt2 != null)
{
delta = (dt2 - dt1).TotalMonths;
}
else
{
delta = 1;
}

or something similar.

Arne
 
I don't think there are any magic.

if(dt1 != null && dt2 != null)
{
     delta = (dt2 - dt1).TotalMonths;}

else
{
     delta = 1;

}

or something similar.

Arne

In VB there is a really useful function named DateDiff. In C# there is
not ...

VisualBasic assembly could always be used but I prefer not to used
it ...

So I came up with the following:

int diff = 12 * (begin.Year - end.Year) + begin.Month - end.Month;
int months = Math.Abs(diff);

Not sure if it is the best option but I think I might implement a
DateDiff method for C#
 
In C# there is no need.  For that matter, DateDiff isn't really needed in  
VB.NET.  It's there for legacy reasons.


DateDiff doesn't address your original question.  Why would you bother to  
try to use it?



In what way does that address your original question?


Why?  What does DateDiff do for you that the operator- overload for  
DateTime doesn't already?

Pete

Sorry Pete,

But does not my code calculate the difference between two dates in
months?

int diff = 12 * (begin.Year - end.Year) + begin.Month - end.Month;
int months = Math.Abs(diff);

I didn't address the nullable DateTime yet.

DateDiff, in my opinion, just creates an "easier" way to calculate
datetime spans in various intervals ...
 
I don't think there are any magic.

if(dt1 != null && dt2 != null)
{
     delta = (dt2 - dt1).TotalMonths;}

else
{
     delta = 1;

}

or something similar.

Arne

Arne,

There isn't a TotalMonths in TimeSpan ... only TotalDays, TotalHours,
TotalSeconds, TotalMinutes and TotalMiliseconds.

That was the first thing I looked.

Thanks,
Miguel
 
It does appear to, yes.  But so does the code that Arne posted.  And his  
also addresses the specific question you actually asked.  More  
importantly, your code has a whole lot of math in it, whereas just using  
the already-overloaded operator- as Arne suggests, you let the DateTime  
type do all the work for you.



No, you didn't.  But that's actually the question you appeared to have  
asked.  A solution that doesn't take into account null values isn't a  
solution at all.


What could be easier that just subtracting one DateTime from another?

Pete

Arne code does not solve it ... It is used TotalMonths which does not
exist in C#. I could use TotalDays / 30 but that wouldn't be accurate.
That is the reason of my code ...

Or maybe as follows:

public static long DateSpan(DateInterval interval, DateTime from,
DateTime to) {

// Define span
TimeSpan span = from - to;

// Check interval
switch (interval) {
case DateInterval.Year:
return to.Year - from.Year;
case DateInterval.Month:
return (to.Month - from.Month) + (12 * (to.Year -
from.Year));
case DateInterval.Weekday:
return CorrectDateSpan(span.TotalDays) / 7;
case DateInterval.Day:
return CorrectDateSpan(span.TotalDays);
case DateInterval.Hour:
return CorrectDateSpan(span.TotalHours);
case DateInterval.Minute:
return CorrectDateSpan(span.TotalMinutes);
default:
return CorrectDateSpan(span.TotalSeconds);
}

} // DateSpan

private static long CorrectDateSpan(double number) {

if (number >= 0) {
return (long)Math.Floor(number);
}
return (long)Math.Ceiling(number);

} // CorrectDateSpan

Note: Didn't tested it yet ...

This function would be a good help specially when I am using this on a
Linq query to define some statistics.

I could include on my function an option that when one of the dates is
null or if from is after to I would return null and then I could set a
default value on my code where I am using the function.
 
There isn't a TotalMonths in TimeSpan ... only TotalDays, TotalHours,
TotalSeconds, TotalMinutes and TotalMiliseconds.

That was the first thing I looked.

Interesting.

It could be because TotalMonths is not very well defined.

Arne
 
shapper said:
Arne code does not solve it ... It is used TotalMonths which does not
exist in C#.

Yep. Sorry about that.
I could use TotalDays / 30 but that wouldn't be accurate.
That is the reason of my code ...

Or maybe as follows:

public static long DateSpan(DateInterval interval, DateTime from,
DateTime to) {

// Define span
TimeSpan span = from - to;

// Check interval
switch (interval) {
case DateInterval.Year:
return to.Year - from.Year;
case DateInterval.Month:
return (to.Month - from.Month) + (12 * (to.Year -
from.Year));

If that is the business logic you want, then that is probably
the way to go.

It is not obvious though that there are 1 months between September
30th and Octobet 1st but 0 months between October 1st and October 31st.

Arne
 
Ah, right.  Sorry.  I just assumed that Arne wouldn't post code that  
doesn't compile; that's more like me to do that, not him.  :)

And yes, you're right...no TotalMonths for TimeSpan.  Which actually makes  
sense, now that I think about it, since TimeSpan is not relative to any  
specific date, and the total months for a TimeSpan would depend on the  
specific date.

My recollection is that the System.Globalization.Calendar class has some  
date/time math functionality in it.  Whether it addresses this specific 
question, I'm not sure, and I don't have time to check at the moment.  But  
you might look at that in the meantime.

You could certainly write the basics yourself, especially if you have only  
a very narrow need (for example, you always know you only need months).  
But if there's something in the framework that accomplishes it, that's  
probably better.  For that matter, if the Calendar class doesn't work,  
maybe referencing the VB assembly is the best solution after all (but it  
still won't deal with the nulls :p ...I really did read your original  
question as being focused on the question of dealing with null values; I  
didn't realize you were asking about the month calculation too).

Pete

Thanks Pete. I will take a look into System.Globalization.Calendar.
 
Yep. Sorry about that.








If that is the business logic you want, then that is probably
the way to go.

It is not obvious though that there are 1 months between September
30th and Octobet 1st but 0 months between October 1st and October 31st.

Arne

Yes, I didn't test it completely but I will check that. But has far as
I know that is also how it works in VB's DateDiff.
 
Sorry Pete,

But does not my code calculate the difference between two dates in
months?


Arne's did that for you...plus it was much easier to read and follow.

Todd
 
Arne code does not solve it ... It is used TotalMonths which does not
exist in C#.

I just want to point out that it has nothing to do with C#. TotalMonths is
not a property of the DateTime class, which belongs to the .NET Framework,
not C#.
 
Back
Top