Allow null DateTime? variable comparison with DateTime variable in C# - c#

I have two variables of type DateTime and DateTime?
DateTime StartDateFromDb;
DateTime? StartDateFromFilter;
if(StartDateFromDb.Date == StartDateFromFilter.Date);
While comparing, .Date is not allowingfor StartDateFromFilter of type allow null
Thanks in advance

Use the Value property available as
if(StartDateFromFilter.HasValue && StartDateFromDb.Date == StartDateFromFilter.Value.Date)
PS: Better to add a null value check. StartDateFromFilter must have a value.(HasValue is true when DateTime? type variable is not null)

For any nullable type , you can use value property.
StartDateFromFilter.Value.Date
In your case , this should work fine
if(StartDateFromDb.Date == StartDateFromFilter.Value.Date)
//// in this case .Date is not allowingfor StartDateFromFilter

Related

Assert Variable is not Null

I have a Variable with type DateTime?
In a Function I check it for being null and want to use it afterwards without always having to ?. every call. In e.g. Kotlin the IDE recognizes a check like that and asserts that the variable cannot be null afterwards. Is there a way to do this in C#?
DateTime? BFreigabe = getDateTime();
if (BFreigabe == null) return false;
TimeSpan span = BFreigabe - DateTime.Now;
//Shows Error because it.BFreigabe has the type DateTime?, even though it can't be null
Edit:
When using
TimeSpan span = BFreigabe.Value - DateTime.Now;
instead it works in this case because .Value doesn't have nullsafety at all. However, considering that this would compile even without the null check and just produce an error, the general question still remains. How can one persuade C# that a former nullable variable isn't nullable any more?
Edit 2
Casting DateTime on the Variable works.
TimeSpan span = (DateTime)BFreigabe - DateTime.Now;
Still not as safe as in Kotlin, but similar enough.
If you have the previous check, you can access the value. Nullable types always have two properties: HasValue and Value.
You could either cast to DateTime (Without the ?) or use the value property.
DateTime? BFreigabe = getDateTime();
if (!BFreigabe.HasValue == null)
return false;
TimeSpan span = BFreigabe.Value - DateTime.Now;
Or store the nullable variable in a non nullable variable:
DateTime? BFreigabe = getDateTime();
if (BFreigabe.HasValue == null)
{
DateTime neverNull = BFreigabe.Value;
TimeSpan span = neverNull - DateTime.Now;
}
This will get full editor support and guarantee that there is no NullReferenceExcpetion.
EDIT: Because your question states Assert. Assert usually means that we will throw an exception if the state is invalid.
In this case, omit the check for nullness. If you access var.Value while var is null, this will throw a NullReferenceException. This moves the responsibility to the caller.
Another option would be to not use the nullable variable. Either by converting it (see the second listing) or by not accepting Nullable types as a parameter.
function TimeSpan Calc(DateTime time)
{
// here we know for sure, that time is never null
}
How about this?
DateTime? BFreigabe = getDateTime();
if (!BFreigabe.HasValue) return false;
DateTime BFreigabeValue = BFreigabe.Value;
TimeSpan span = BFreigabeValue - DateTime.Now;
Try to convert NULL value to any value, that is irrelevant.
DateTime? BFreigabe = getDateTime();
if (BFreigabe == null) return false;
TimeSpan span = (BFreigabe??DateTime.Now) - DateTime.Now;

Nullable DateTime in C#

I have two questions related to DateTime assingments
DateTime? y = 1 == 1 ? null: DateTime.MaxValue;
DateTime? y = null; // assignment works as expected
Why the first assignment issues error of type conversion between null and DateTime?
Which is the preferred way for null assignments of DateTime? in c#.
DateTime? x = default(DateTime?); //prints null on console
DateTime? x = null; // prints null on console
DateTime? x = DateTime.MinValue; //print 01/01/0001
The second statement DateTime? y = null; is only an assignment of null to a nullable object.
Whereas the first is a conditional assignment, which assigns some value for the true state and some other value for the false; Here you are using the conditional operator for evaluating the condition. according to MSDN first_expression (executes if true) and second_expression*(executes if false)* must be of same type or an implicit conversion must exist from one type to the other. In our case both are different so The simple solution is doing an explicit conversion as like this:
DateTime? y = 1 == 1 ?(DateTime?) null : DateTime.MaxValue;
A1. Because in ternary operator both expressions/results should be of same type.
Acc. to MSDN Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
In your question, null and DateTime.MinValue do not match and hence the error conversion between null and DateTime.
You can do
DateTime? y = 1 == 1 ? null : (DateTime?)DateTime.MaxValue;
This way both answers return an answer whose type is DateTime?.
A2. Normally there is no said/preferred way of assigning this. This depends on user convention. All three are good and depend on user requirements.
Because ?: Operator operator expects same type on both sides.
Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.
So solution will be like below:
DateTime? y = 1 == 1 ? (DateTime?)null : DateTime.MaxValue;
And for second question, this will be good way for null assignment
DateTime? x = null;
DateTime? y = 1 == 1 ? null: DateTime.MaxValue;
This statement is giving an assignment error not because of the null assignment to a variable it is because of using null assignment in ternary operator and as you are using a class type here you the ternary operator do not lead you to do this illegal stuff as per CLR specifications mentioned,It might give you a straight compilation error.
//Which is the preferred way for null assignments of DateTime? in c#.
DateTime? x = default(DateTime?); //prints null on console
DateTime? x = null; // prints null on console
DateTime? x = DateTime.MinValue; //print 01/01/0001
As per Specifications and guidelines provided the Class Types should not be assigned null in any scenario so as per standard you can use the min value(though you can use default value too but it might effect in type conversions when needed)
The second one that you mentioned. You need to cast null value in this time asmensioned by Sir Nikhil Agrawal.
Ternary
int y = 1;
DateTime? dt3 = y == 1 ? (DateTime?)null : DateTime.MinValue;
Traditional way
DateTime? dt3 = null;
if (y == 1)
dt3 = null;
else
dt3 = DateTime.MinValue;
if you want to cast null to nullable datetime then you can use
DateTime? dt = (DateTime?)null;

How can someone handle default datetime

I have DAL where I convert database null value to their equivalent representation in C#. For example:
NULL for Numeric = 0
NULL for String = String.Empty
NULL for DateTime = "1/1/0001" (i.e. DateTime.MinValue)
The problem, for date, lies in the presentation layer, especially in GridViews. You cannot show 1/1/01 to users.
What I used to do is check if myDate.Year=1 or myDate.Year < AcceptedDate and display empty string, but seems to be extra effort unlike other types
Please am open to better approach. Thanks.
Use Nullable datatype to store null value.
DateTime? value = null;
int? myNullableInt = 1;
value = DateTime.Now;
How to check whether variable has value or null
if (value!=null)
String value can store null, so there is no diffrent datatype for string to store null.
string var;
if (var == null)
or
if (String.IsNullOrEmpty(var))
You can also use DateTime.MinValue constant.
http://msdn.microsoft.com/en-us/library/system.datetime.minvalue.aspx
Your conditions would be:
if (myDate == DateTime.MinValue)
You can use Nullable DateTime, so you will return DateTime? instead of DateTime from your DAL. This way you can check if returned value is null.
DateTime? dateTime = null;
As the others mention, you could use a System::Nullable<DateTime>.
The other approach I've seen is to use a standard DateTime and just use a special value such as DateTime.MinValue. This is useful if you need to honor an existing interface's types and can't change the DateTime to a Nullable<DateTime>.
You can either use a Nullable DateTime as the others suggested, or use this trick:
(To prevent non valid defaults.)
// If dateTime has not been initialize, initialize to Now
// (or to any other legal inital values)
dateTime = ((dateTime != new DateTime()) ? dateTime : DateTime.Now);
This trick is useful if you have to use a non-nullable DateTime and want to provide a default if none. (E.g. you have a non-nullable DateTime column in a DB and want to set the value only if row is new.)
I don't think you have much choice but to make the check like you have been and display accordingly. A nullable type might make things easier for you. Depending on your data, even the numeric should be treated this way. DBNull != 0.

How to do Conditional check Date should not be blank in C#?

I have a date model ( project.CreateDate ) in my c# project, how do i can conditionally check that Date is not null, like
//i know this can not be applied, because it is type of Date and string
if (project.CreateDate != "" ){
//other process
}
so how do i can check?
If .CreateDate is of type System.Nullable<DateTime> you could easily do the following check:
if (project.CreateDate.HasValue)
or
if (project.CreateDate != null)
and maybe enhance this with
if (project.CreateDate.HasValue && DateTime.MinValue < project.CreateDate.Value)
Otherwise you might go the ugly path eg
if (project.CreateDate != DateTime.MinValue)
or
if (DateTime.MinValue < project.CreateDate)
If .CreateDate is of type System.String you go for
if (!string.IsNullOrEmpty(project.CreateDate))
or with .NET 4.0 and System.String
if (!string.IsNullOrWhiteSpace(project.CreateDate))
I strongly encourage you to use System.Nullable<DateTime> (aka System.DateTime?) to go for the first solution. The value System.DateTime.MinValue might always be a "non-real"-value, but you will lose the possibility of using System.DateTime.MinValue in your application (compare to not be able to use 0 in your application) as a real-value
A DateTime that is not set otherwise to a given date will have a default value of DateTime.MinValue. You can compare against that:
if (project.CreateDate != DateTime.MinValue)
{
// can use date
}
If it is actually a nullable date (Nullable<DateTime> or just DateTime?), the default value will simply be the functional equivalent of null.
if (project.CreateDate != null) // for nullable dates
Date is a value type so if the variable is not declared as nullable, if it is you can use project.CreateDate.HasValue, othwerise you can test it against the default value:
if (project.CreateDate != default(DateTime))
{
}

Nullable Object must have a value #2

I'm trying to reuse the same code I've always used but now it is encountering an error.
I'm looping through various user tables, and in there I do this:
DateTime dcdt = (DateTime)u.DateCreated;
DateTime lldt = (DateTime)u.LastLogon;
userRow["DateCreated"] = dcdt.ToShortDateString();
inside the loop. I get the error:
System.InvalidOperationException: Nullable object must have a value.
The error highlights "lldt" line, instead of "dcdt" which comes first. That is strange in and of itself. Both these fields in the database "allow nulls" is checked. And they both could be null or neither might be null.
The two values are both listed as DateTime? types through intellisense.
I don't understand why ASP.NET refuses to allow me to output blank for null dates. If it is empty/null, then logic would suggest that ASP.NET should just print nothing.
How else am I suppose to output null dates? I tried adding if statements to prevent trying to cast null DateTimes, but it doesn't help, it makes no sense.
As you've said, the data type of u.LastLogon is DateTime?. This means that it may or may not have a value. By casting to DateTime, you are requiring it to have a value. In this case, it does not.
Depending on what you're trying to do with it, you may want to check the HasValue property:
userRow["LastLogon"] = u.LastLogin.HasValue ?
(object) u.LastLogin.ToShortDateString() : DBNull.Value;
If your database LastLogon column is of DateTime type, then you should be able to do:
userRow["LastLogon"] = u.LastLogin.HasValue ?
(object) u.LastLogin.Value : DBNull.Value;
You need to do something like the following in your data access code:
DataTable dt = ExecuteSomeQuery() ;
object value = dt.Rows[0]["nullable_datetime_column"] ;
DateTime? instance = value != null && value is DateTime ? (DateTime?)value : (DateTime?)null ) ;
If the column returned is NULL, it will be returned as a System.DBNull, otherwise it will be returned as an instance of DateTime (or whatever the appropriate mapped type is — int, string, etc). Consequently, you need to check the type of object returned from the query before trying to cast it.
Looks like you are trying to call a method (dcdt.ToShortDateString()) on a DateTime? which doesn't have a value (it is, indeed, null). Try this:
dcdt.HasValue ? dcdt.ToShortDateString() : String.Empty;
EDIT (Just re-read the question): Also, don't try to convert to DateTime. Preserve the nullable.
EDIT #2 (based on comments):
Try this:
if (dcdt.HasValue)
{ userRow["DateCreated"] = dcdt.ToShortDateString(); }
else
{ userRow = DbNull.Value }
I saw that Dexter asked how he should go about it. Well, I would create an extension.
static class DateTimeExtensions
{
public static string ToString(this DateTime? dateTime, string format)
{
return dateTime.HasValue ? dateTime.Value.ToString(format) : String.Empty;
}
}
And then you can do:
DateTime? dt = null;
DateTime? dt2 = DateTime.Now;
Console.WriteLine(dt.ToString("dd-MM-yy"));
Console.WriteLine(dt2.ToString("dd-MM-yy"));
Note that I can call extension method on a nullable type if the object is null.
The problem is .NET null is not the same as SQL NULL. SQL Null is System.DBNull. So it is a [non-null] value in .NET.
Short answer
DateTime? dateTime = u.LastLogon?.ToShortDateString()

Categories

Resources