how do i check if DateTime is null - c#

if (string.IsNullOrEmpty(value)) is for string, but what is the code to check if Datetime is null?
private DateTime? _ReleaseDate;
public DateTime? ReleaseDate
{
get
{
return _ReleaseDate;
}
set
{
if ()
{
}
else
{
_ReleaseDate = value;
}
}
}

The ValueType? pattern is shorthand for Nullable<ValueType>. In your case you have Nullable<DateTime>.
As you can see from the docs, Nullable<ValueType> implements a HasValue property, so you can simply check it like so:
if (value.HasValue)
{
}
else
{
}
If you simply want to set a default value you can use the GetValueOrDefault method of Nullable<T> and do away with the if statement:
_ReleaseDate = value.GetValueOrDefault(DateTime.MinValue); // or whatever default value you want.

For nullbale types you can use HasValue or != null
However for your example (with the code shown), you have more options
public DateTime? ReleaseDate
{
get
{
return _ReleaseDate;
}
set
{
// if value is null, then that's all good, _ReleaseDate will be null as well
_ReleaseDate = value;
}
}
Or
public DateTime? ReleaseDate {get;set}
The only reason you would need to do something like below, is when you have some specific behaviour on null or otherwise
public DateTime? ReleaseDate
{
get
{
return _ReleaseDate;
}
set
{
if (value.HasValue)
{
// has a value
}
else
{
// doesnt
}
}
}

Related

set max date value in database model

Hi all I am trying to set max date below
But Modified always returns a null value instant of return max value between ModifiedDate and OfferProductsModified.
public DateTime? Modified { get { return _FinalDate; } set { _FinalDate = value; } }
/// <summary>
/// this are not in offer view model
/// </summary>
[JsonIgnore] public DateTime? _FinalDate;
[JsonIgnore]
public DateTime? FinalDate
{
get
{
if (ModifiedDate < OfferProductsModified)
{
return OfferProductsModified;
}
else
{
return ModifiedDate;
}
}
set
{
if (ModifiedDate < OfferProductsModified)
{
_FinalDate = OfferProductsModified;
}
else
{
//DEFAULT Value.
_FinalDate = value;
}
}
}
How can I return the max value between ModifiedDate and OfferProductsModified ?
Note :- Both ModifiedDate and OfferProductsModified having values (confirm by debugging )

Setting a dateTime property to null

I have this class which is a nuget package with a nullable dateTime property. This property is set depending on when another property is filled. Now, I do not want this property to have this property and I will like to set it null. Here is the class in the private nuget package
public class myClass
{
private string _todaysDate;
public DateTime? todaysDateAsDateTime
{
get
{
DateTime? result;
return !this.todaysDate.TryParseToDate(out result) ? new DateTime?() : result;
}
set => this.todaysDate = value.ParseToDate();
}
public string todaysDate
{
get => this._todaysDate;
set => this._todaysDate= value;
}
}
ParseToDate and TryParseToDate are extension menthods in thesame nuget
public static string ParseToDate(this DateTime? value) => value?.ToString("yyyy-MM-dd", (IFormatProvider) CultureInfo.InvariantCulture);
public static bool TryParseToDate(this string value, out DateTime? result)
{
if (string.IsNullOrEmpty(value))
{
result = new DateTime?();
return true;
}
bool flag = false;
DateTime result1 = DateTime.UtcNow;
if (value.Length == 10)
flag = DateTime.TryParseExact(value, "yyyy-MM-dd", (IFormatProvider) CultureInfo.InvariantCulture, DateTimeStyles.None, out result1);
if (flag)
{
result = new DateTime?(DateTime.SpecifyKind(result1, DateTimeKind.Utc));
return true;
}
result = new DateTime?();
return false;
}
when using this class, is there a possibility of setting todaysDateAsDateTime to null? because I do not want to have this value. The todaysDate is filled by the program when I use it in my application
In the property todaysDateAsDateTime, you need manage case in get/set when the value is null :
public class myClass
{
private string _todaysDate;
public DateTime? todaysDateAsDateTime
{
get =>
this._todaysDate != null && this._todaysDate.TryParseToDate(out DateTime? result) ?
result : null;
set => this._todaysDate = value?.ParseToDate();
}
public string todaysDate
{
get => this._todaysDate;
set => this._todaysDate = value;
}
}
I think you begin with C#, I add the same code without sugar syntax :
public class myClass
{
private string _todaysDate;
public DateTime? todaysDateAsDateTime
{
get
{
DateTime? result;
if(this._todaysDate!=null && this.todaysDate.TryParseToDate(out result))
{
return result;
}
else
{
null;
}
}
set
{
if(value != null)
{
this._todaysDate = value.ParseToDate();
}
else
{
this._todaysDate = null;
}
}
}
public string todaysDate
{
get => this._todaysDate;
set => this._todaysDate = value;
}
}

"Data is Null. This method or property cannot be called on Null values." on DateTime [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
c# why cant a nullable int be assigned null as a value
Im trying to convert my reader[3] object which is datetime to be null if there is no lastPostDate for a Forum but it says Im missing a conversion.
Error:
Type of conditional expression cannot be determined because there is no implicit conversion between <null> and 'System.DateTime'
public class Forums
{
public List<Forum> GetForums()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CMS"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("sproc_Forums_GetForums", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default);
List<Forum> forums = new List<Forum>();
while (reader.Read())
{
var title = reader[6].ToString();
var threadCount = (int)reader[5];
var lastPostTitle = reader[4].ToString();
// below is where im having a problem
Nullable<DateTime> lastPostDate = (reader[3] == DBNull.Value ? null : Convert.ToDateTime(reader[3]));
var lastPostBy = reader[2].ToString();
var forumGroup = reader[1].ToString();
var description = reader[0].ToString();
Forum forum = new Forum(0, "",DateTime.Now,
reader["Title"].ToString(),description,
0,false,"","",DateTime.Now,true,
forumGroup, (int)threadCount, lastPostBy,
lastPostDate, lastPostTitle);
forums.Add(forum);/**/
}
return forums;
}
}
}
Below is my class object for Forum with a Nullable lastPostDate
public class Forum
{
public Forum(int forumID, string addedBy, DateTime addedDate, string title, string description, int parentID, bool moderated,
string imageUrl, string updatedBy, DateTime? updatedDate, bool active, string forumGroup, int threadCount, string lastPostBy,
Nullable<DateTime> lastPostDate, string lastPostTitle)
{
this.ForumID = forumID;
this.AddedBy = addedBy;
this.AddedDate = addedDate;
this.Title = title;
this.Description = description;
this.ParentID = parentID;
this.Moderated = moderated;
this.ImageUrl = imageUrl;
this.UpdatedBy = updatedBy;
this.UpdatedDate = updatedDate;
this.Active = active;
this.ForumGroup = forumGroup;
this.ThreadCount = threadCount;
this.LastPostBy = lastPostBy;
this.LastPostDate = lastPostDate;
this.LastPostTitle = lastPostTitle;
}
private int _forumID;
public int ForumID
{
get { return _forumID; }
set { _forumID = value; }
}
private string _addedBy;
public string AddedBy
{
get { return _addedBy; }
set { _addedBy = value; }
}
private DateTime _addedDate = DateTime.Now;
public DateTime AddedDate
{
get { return _addedDate; }
set { _addedDate = value; }
}
private string _title = "";
public string Title
{
get { return _title; }
set { _title = value; }
}
private string _description = "";
public string Description
{
get { return _description; }
set { _description = value; }
}
private int _parentID = 0;
public int ParentID
{
get { return _parentID; }
set { _parentID = value; }
}
private bool _moderated = false;
public bool Moderated
{
get { return _moderated; }
set { _moderated = value; }
}
private string _imageUrl = "";
public string ImageUrl
{
get { return _imageUrl; }
set { _imageUrl = value; }
}
private string _updatedBy = "";
public string UpdatedBy
{
get { return _updatedBy; }
set { _updatedBy = value; }
}
private DateTime? _updatedDate = null;
public DateTime? UpdatedDate
{
get { return _updatedDate; }
set { _updatedDate = value; }
}
private bool _active = false;
public bool Active
{
get { return _active; }
set { _active = value; }
}
private string _forumGroup = "";
public string ForumGroup
{
get { return _forumGroup; }
set { _forumGroup = value; }
}
private int _threadCount = 0;
public int ThreadCount
{
get { return _threadCount; }
set { _threadCount = value; }
}
private string _lastPostBy = "";
public string LastPostBy
{
get { return _lastPostBy; }
set { _lastPostBy = value; }
}
private Nullable<DateTime> _lastPosteDate = null;
public Nullable<DateTime> LastPostDate
{
get { return _lastPosteDate; }
set { _lastPosteDate = value; }
}
private string _lastPostTitle = "";
public string LastPostTitle
{
get { return _lastPostTitle; }
set { _lastPostTitle = value; }
}
}
You might want to do it like this:
DateTime? lastPostDate = (DateTime?)(reader.IsDbNull(3) ? null : reader[3]);
The problem you are having is that the ternary operator wants a viable cast between the left and right sides. And null can't be cast to DateTime.
Note the above works because both sides of the ternary are object's. The object is explicitly cast to DateTime? which works: as long as reader[3] is in fact a date.
Make sure those two types are nullable DateTime
var lastPostDate = reader[3] == DBNull.Value ?
null :
(DateTime?) Convert.ToDateTime(reader[3]);
Usage of DateTime? instead of Nullable<DateTime> is a time saver...
Use better indent of the ? expression like I did.
I have found this excellent explanations in Eric Lippert blog:
The specification for the ?: operator states the following:
The second and third operands of the ?: operator control the type of
the conditional expression. Let X and Y be the types of the second and
third operands. Then,
If X and Y are the same type, then this is the type of the conditional
expression.
Otherwise, if an implicit conversion exists from X to Y,
but not from Y to X, then Y is the type of the conditional expression.
Otherwise, if an implicit conversion exists from Y to X, but not from
X to Y, then X is the type of the conditional expression.
Otherwise,
no expression type can be determined, and a compile-time error occurs.
The compiler doesn't check what is the type that can "hold" those two types.
In this case:
null and DateTime aren't the same type.
null doesn't have an implicit conversion to DateTime
DateTime doesn't have an implicit conversion to null
So we end up with a compile-time error.
Cast the null literal: (DateTime?)null or (Nullable<DateTime>)null.
You can also use default(DateTime?) or default(Nullable<DateTime>)
And, as other answers have noted, you can also apply the cast to the DateTime value rather than to the null literal.
EDIT (adapted from my comment to Prutswonder's answer):
The point is that the conditional operator does not consider the type of its assignment target, so it will only compile if there is an implicit conversion from the type of its second operand to the type of its third operand, or from the type of its third operand to the type of its second operand.
For example, this won't compile:
bool b = GetSomeBooleanValue();
object o = b ? "Forty-two" : 42;
Casting either the second or third operand to object, however, fixes the problem, because there is an implicit conversion from int to object and also from string to object:
object o = b ? "Forty-two" : (object)42;
or
object o = b ? (object)"Forty-two" : 42;
You can try this
var lastPostDate = reader[3] == DBNull.Value ?
default(DateTime?):
Convert.ToDateTime(reader[3]);

Validation inside a class property

The code is as follows:
public class MyEvent
{
public string EventTitle { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public bool IsInsideSameMonth
{
get
{
// No code is bug-free, so we assume this situation may occur somehow.
if (StartDate > EndDate)
{
// And when this occurs, we want to halt the application by throwing exception to prevent further potential damage.
throw new MyEventException("Start date is not supposed to be greater than end date.");
}
return (StartDate.Year == EndDate.Year && StartDate.Month == EndDate.Month);
}
}
public void Validate()
{
if (StartDate > EndDate)
{
throw new MyEventException("Start date is not supposed to be greater than end date.");
}
if (String.IsNullOrWhiteSpace(EventTitle))
{
throw new MyEventException("Title cannot be empty.");
}
}
}
public class MyEventException : Exception
{
public MyEventException(string message)
: base(message)
{
}
}
It might seem redundant that I perform StartDate > EndDate validation inside the IsInsideSameMonth property. I just prefer being on the safe side. But it feels as if I am doing something wrong but I cannot describe it.
Is this a good practice? Please share your valuable experience and thoughts.
You shouldn't use Auto-implemented property. You should instead use a backing private field and then check while setting the property like:
private DateTime _StartDate;
public DateTime StartDate
{
get { return _StartDate; }
set
{
if (value > _EndDate)
{
throw new MyEventException("Start date is not supposed to be greater than end date.");
}
else
{
_StartDate = value;
}
}
}
private DateTime _EndDate;
public DateTime EndDate
{
get { return _EndDate; }
set { _EndDate = value; }
}
Your current code would allow the user to set StartDate to any value and you will only realize if you check your property IsInsideSameMonth.
For the EventTitle you could declare a backing field and make the validation inside the setter of the property. Something like this:
string eventTitle;
public string EventTitle
{
get
{
return eventTitle;
}
set
{
if(!IsNullOrWhiteSpace(value))
eventTitle = value;
else
throw new MyEventException("Title cannot be empty.");
}
}
As for the DateTime objects you could follow the same path:
private DateTime startDate;
public DateTime StartDate
{
get
{
return startDate;
}
set
{
if (value > EndDate)
{
throw new MyEventException("Start date is not supposed to be greater than end date.");
}
else
{
startDate = value;
}
}
}
private DateTime endDate;
public DateTime EndDate
{
get
{
return endDate;
}
set
{
endDate = value;
}
}
It's better to control values when the properties are set, so you need to convert your automatic properties to old style (properties with private field) and put your checking there.
Here is the Microsoft property design guide.
Here is an example checking the values when setting, throwing if invalid. I've also defined functions for validation to reduce redundant code (in case you want to change your validation or error messaging- it will be in one location).
public class MyEvent
{
public bool IsInsideSameMonth
{
get
{
return (StartDate.Year == EndDate.Year && StartDate.Month == EndDate.Month);
}
}
private string _EventTile;
public string EventTitle
{
get { return _EventTile; }
set
{
ValidateTitle(value); // this will throw if invalid and leave the value of _EventTitle unchanged
_EventTile = value;
}
}
private DateTime _StartDate = DateTime.MinValue;;
public DateTime StartDate
{
get { return _StartDate; }
set
{
ValidateDates(value, EndDate); // this will throw if invalid and leave the value of _StartDate unchanged
_StartDate = value;
}
}
private DateTime _EndDate = DateTime.MaxValue;;
public DateTime EndDate
{
get { return _EndDate; }
set
{
ValidateDates(StartDate, value); // this will throw if invalid and leave the value of _EndDate unchanged
_EndDate = value;
}
}
private void ValidateDates(DateTime start, DateTime end)
{
if (start > end)
{
throw new MyEventException("Start date is not supposed to be greater than end date.");
}
}
private void ValidateTitle(string title)
{
if (String.IsNullOrWhiteSpace(title))
{
throw new MyEventException("Title cannot be empty.");
}
}
public void Validate()
{
ValidateDates(StartDate, EndDate);
ValidateTitle(EventTitle);
}
}
public class MyEventException : Exception
{
public MyEventException(string message)
: base(message)
{
}
}

Return a null from Function which returns a DateTime

public static DateTime ResolveDate()
{
return null;
}
Im required to return a null value from a function which returns a DateTime Type .. My Main Objective is to NOT to use MinValue or return a new Datetime(); [Which Returns a Default Date] and Frontend display the Date as a Empty Value (Blank) -> ""
public static DateTime? ResolveDate()
{
if ( someconditon = true )
{
return DateTime.Now
}
else
{
return null;
}
}
An alternative is to use something like TryParse is working
Public static bool TryResolve (out Resolvedate)
{
if ( someconditon = true )
{
Resolvedate = DateTime.Now
return true;
}
else
{
return false;
}
}
Make it nullable
public static DateTime? ResolveDate()
{
return null;
}
You can then return null as you want and check accordingly
Have a read of this Nullable Types for more information.
You can either return a Nullable<DateTime> like so:
public static DateTime? ResolveDate()
{
if (notResolvable)
{
return null;
}
}
Which would be useable like so:
var date = ResolveDate();
if (date.HasValue)
{
// Use date.Value here
}
Or use the Try naming convention like so:
public static bool TryResolveDate(out DateTime date)
{
date = default(DateTime);
if (notResolvable)
{
return false;
}
}
Which would be useable like so:
DateTime date;
if (TryResolveDate(out date))
{
// Use date here
}
bool somecondition = true;
public DateTime? ResolveDate()
{
DateTime? date = null;
if (somecondition == true)
{
date = DateTime.Now;
return DateTime.Now;
}
else return date;
}

Categories

Resources