I'm converting a small MSAccess application to a web-based ASP.NET app, using C# 3.5. I was wondering what's the best way to work with dates in C#, when converting some of this VBA code over to C#.
Here is an example of the VBA Code:
Coverage1=IIf(IsNull([EffDate1]),0,IIf([CurrDate]<=[EndDate1],[CurrDate]-[EffDate1],[EndDate1]-[EffDate1]+1))
Here is what my current C# code looks like with the errors denoted in the commented code:
public DateTime CalculateCoverageOne(DateTime dateEffDateOne, DateTime dateCurrentDate, DateTime dateEndDateOne)
{
if (dateCurrentDate.Date <= dateEndDateOne.Date)
{
return null; //Get "cannot convert null to System.DateTime because it is a non-nullable value type" error
}
else
{
if (dateCurrentDate.Date <= dateEndDateOne)
{
return dateCurrentDate.Subtract(dateEffDateOne); //Gets error "cannot implicitly convert system.timepsan to system.datetime
}
else
{
return dateEndDateOne.Subtract(dateEffDateOne.AddDays(1)); //Gets error "cannot implicitly convert system.timepsan to system.datetime
}
}
}
cannot convert null to System.DateTime because it is a non-nullable value type" error
The DateTime
type is a value type, which means that it cannot hold a null value. To get around this you can do one of two things; either return DateTime.MinValue
, and test for that when you want to use the value, or change the function to return DateTime?
(note the question mark), which is a nullable DateTime
. The nullable date can be used like this:
DateTime? nullable = DateTime.Now;
if (nullable.HasValue)
{
// do something with nullable.Value
}
cannot implicitly convert system.timepsan to system.datetime
When you subtract a DateTime
from another DateTime
, the result is a TimeSpan
, representing the amount of time between them. The TimeSpan
does not represent a specific point in time, but the span itself. In order to get the date, you can use the Add
method or the Subtract
method overload of a DateTime
object that accepts a TimeSpan
. Exactly how that should look I can't say, since I don't know what the different dates in your code represent.
In the last case, you can simply use the return value from the AddDays method, but with a negative value (in order to subtract one day, instead of adding one):
return dateEffDateOne.AddDays(-1);
It looks like your VB is actually returning a time span, presumably in days. Here's the closest direct translation:
public TimeSpan CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1)
{
return (EndDate1 == null) ? TimeSpan.Zero :
(CurrDate < EndDate1) ? (CurrDate - EffDate1) :
(EndDate1.AddDays(1) - EffDate1);
}
If instead you just wanted a count of days, just return the TimeSpan's Days property:
public int CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1)
{
return ((EndDate1 == null) ? TimeSpan.Zero :
(CurrDate < EndDate1) ? (CurrDate - EffDate1) :
(EndDate1.AddDays(1) - EffDate1)).Days;
}
And for good measure, this is how I would clean up your final version:
public int CalculateCoverageOne(DateTime dateCurrentDate, DateTime dateEffectiveDate, DateTime dateEffDateOne, DateTime dateEndDateOne)
{
TimeSpan ts;
if (dateEffDateOne == DateTime.MinValue)
{
ts = TimeSpan.Zero;
}
else if (dateEffectiveDate <= dateEndDateOne)
{
ts = dateCurrentDate - dateEffDateOne;
}
else
{
ts = (dateEndDateOne - dateEffDateOne) + new TimeSpan(1, 0, 0, 0);
}
return ts.Days;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With