How to check null or datetime value using ternary operator? - c#

I want to check passed value is null or datetime value using ternary operator in c#?
I tried like this
fromDate == null ? null : Convert.ToDateTime(fromDate)
getting error:
type of conditional expression cannot be determined
I want to check whether variable fromDate is null or having date time value ?
variable fromDate is coming from Querystring and type of string.

From ?: Operator:
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.
condition ? first_expression : second_expression;
Convert.ToDateTime returns DateTime and there is no implicit conversion between null and DateTime. And the conditional operator is an expression and that needs a return type.
One option seems logical to me using DateTime.TryParse (which returns boolean) as a first expression and use another boolean (true or false) as a second expression. Damiths' answer seems logical.
Or instead you can use nullable DateTime like DateTime?
DateTime? foo;
if(foo.HasValue)
{
//Nullable DateTime has a value..
}

if you have string value for fromDate do as below
DateTime dt;
bool isValidDate = String.IsNullOrEmpty(fromDate) ? false : DateTime.TryParse(fromDate, out dt);
if you know the datetime format/formats which your input having you better use DateTime.TryParseExact method
if fromDate is DateTime, then simple you can check as below
fromDate.HasValue
you don't need ?: Operator

The problem is that Convert.ToDateTime(fromDate) is of type DateTime, which cannot accept a null value, that is why this code won't work in this form. You have two choices to make. Either change it to regular if:
if(fromDate != null)
{
Convert.ToDateTime(fromDate)
}
Or cast DateTime to nullable DateTime:
fromDate == null ? null : (DateTime?)Convert.ToDateTime(fromDate)
Ternary operator in C# needs both values to be of the same type and it is explained here.

romDate == null ? null : Convert.ToDateTime(fromDate)
null and Convert.ToDateTime(fromDate) haven't common type. Compiler must be able to cast both expressions in canditional operator to same type.

I hope it will help you
string format = "ddd dd MMM h:mm tt yyyy";
DateTime dateTime;
fromDate=(DateTime.TryParseExact(fromDate, format, CultureInfo.InvariantCulture,
DateTimeStyles.None, out dateTime))?dateTime:null;

you must use String.IsNullOrEmpty to check if fromDate is null like this:
DateTime? date = String.IsNullOrEmpty(fromDte) ? null : (DateTime?)Convert.ToDateTime(fromDate)

It looks like the main problem is that you are trying to assign null to a DateTime
DateTime is a structure and not a reference type so this can't be done.
Either use a nullable DateTime (DateTime?) or a specific value to indicate null, such as DateTime.MinValue
Have a look here for an example: http://www.dotnetperls.com/nullable-datetime

Related

How to cast a nullable DateTime to UTC DateTime

I'm reading back a DateTime? value from my view. Now I check to see if the NextUpdate DateTime? HasValue and if so convert that time to UTC.
From reading up on this it seems I need to use a null coalescing operator but my assignment tells me that System.NUllable does not contain a definition for ToUniversalTime() when using that operator.
I've searched on SO for a similar question but no luck on that.
Question:
How can I convert a null DateTime value to UTC?
Code:
I'm simply checking if the DateTime? has a value, and if so convert that DateTie to UTC -
if (escalation.NextUpdate.HasValue)
{
escalation.NextUpdate = escalation.NextUpdate ?? escalation.NextUpdate.ToUniversalTime();
}
else
{
escalation.NextUpdate = null;
}
My NextUpdate property in the model:
public DateTime? NextUpdate { get; set; }
Your code is wrong in more than one way.
The ?? operator returns the left side if it is not null, otherwise the right side.
Since you already checked that escalation.NextUpdate.HasValue is true, the left side is not null and you assign the same date again (without converting to UTC).
Nullable<DateTime> does not declare ToUniversalTime(), you need to do that on the value.
So the final code should look like this:
if (escalation.NextUpdate.HasValue)
escalation.NextUpdate = escalation.NextUpdate.Value.ToUniversalTime();
or with C#6
escalation.NextUpdate = escalation.NextUpdate?.ToUniversalTime();
There is no need for the else branch as in that case it would be null anyway.
if you are using c#6 then its very simple
escalation.NextUpdate?.ToUniversalTime();
this translates as if NextUpdate is not null call ToUniversalTime() else return null
if you can't use c#6 then inline if is probably your best bet
escalation.NextUpdate.HasValue ? (DateTime?)escalation.NextUpdate.Value.ToUniversalTime():null;
this is basically the same as your full if baring you've missed out the Value property of the nullable and corrects your use of the ?? operator

C# ternary use results of method (with datetime variable)

I have an issue that I'd like to work around
I have declared a nullable DateTime and I'm trying to put either a date in it or a null value using a ternary operator.
This does not work:
DateTime? date;
date = getDate() == DateTime.MinValue ? null : getDate()
My own code is a bit more elaborate but basically what I'd like to use is
date = getDate() == DateTime.MinValue ? null : resultofgetDate()withoutactuallyrunningitagain
I don't want to do the function twice, but in this case as a bonus, since it's datetimes, it also gives an error in the else section saying
There is no implicit conversion between 'null' and 'System.DateTime' in my first example.
I'm not sure in what direction to look. I seem to need the opposite of the null coalescing operator (??).
There is no such operator. You can write something like this:
DateTime? date = getDate();
date = date == DateTime.MinValue ? null : date;
It seems as if getDate() is returning a DateTime and not a DateTime? (aka Nullable<DateTime>). The values used in ternary expressions have to be of the same type which is why you are getting your error.
Your first example should work with
date = getDate() == DateTime.MinValue ? null : (DateTime?)getDate()`
as pointed out in MaKCbIMKo's answer.
I'm assuming you return DateTime.MinValue as some sort of error handling / validation. If you change the method signature so it returns a DateTime? you can return null instead, then your statement becomes date = getDate()
Have you tried something like:
DateTime? date;
var dt = getDate();
date = dt == DateTime.MinValue ? (DateTime?)null : dt;
Hope it will help.
Please, do it as Rob described, but here is my take on an extension method:
public static T? Test<T>(this T? value, Predicate<T?> test, T? ifEquals) where T : struct
{
if (test(value))
{
return ifEquals;
}
return value;
}
Use it like this:
DateTime? d = GetDate().Test(t => t == DateTime.MinValue, null);
You can also create this extension method (one of the overloads calls the other one):
public static T? NullIfHasDefaultValue<T>(this T v) where T : struct
{
return EqualityComparer<T>.Default.Equals(v, default(T)) ? (T?)null : v;
}
public static T? NullIfHasDefaultValue<T>(this T? n) where T : struct
{
return n.GetValueOrDefault().NullIfHasDefaultValue();
}
Of course use it as getDate().NullIfHasDefaultValue().

Using DateTime with Null

I have this line of code here:
command.Parameters["#DateCompleted"].Value = items[i].DateCompleted.Equals("01/01/0001 12:00:00 AM") ? null : items[i].DateCompleted;
but I got this error:
Type of conditional expression cannot be determined because there is no implicit conversion between '<null>' and 'System.DateTime'
What I am trying to do is not use the 01/01/0001 Date and use null because the item is null.
Additional Code:
command.Parameters.Add("#DateCompleted", System.Data.SqlDbType.DateTime);
Simply cast the null to a DateTime?. Also, assuming DateCompleted is a DateTime (it should be), then don't compare against a string, but against DateTime.MinValue instead.
command.Parameters["#DateCompleted"].Value =
items[i].DateCompleted.Equals(DateTime.MinValue)
? (DateTime?) null
: items[i].DateCompleted;
Use DateTime?
command.Parameters["#DateCompleted"].Value =
items[i].DateCompleted.Equals("01/01/0001 12:00:00 AM") ? (DateTime?)null :
items[i].DateCompleted;
To use the ternary operator where one of the return types is null, the other return type has to be a nullable type, which DateTime is not, being a struct. What you could do is replace the null with default(DateTime):
DateTime value = someCondition ? default(DateTime) : items[i].DateCompleted;

Set an empty DateTime variable

I would declare an empty String variable like this:
string myString = string.Empty;
Is there an equivalent for a 'DateTime' variable ?
Update :
The problem is I use this 'DateTime' as a parameter for a 'StoredProcedure' in SQL.
E.g:
DateTime? someDate = null;
myCommand.Parameters.AddWithValue("#SurgeryDate", someDate);
When I run this code an exception is catched telling me the 'StoredProcedure' expected a '#SurgeryDate' parameter.
But i provided it.
Any idea why?
Since DateTime is a value type you cannot assign null to it, but exactly for these cases (absence of a value) Nullable<T> was introduced - use a nullable DateTime instead:
DateTime? myTime = null;
No. You have 2 options:
DateTime date = DateTime.MinValue;
This works when you need to do something every X amount of time (since you will always be over MinValue) but can actually cause subtle errors (such as using some operators w/o first checking if you are not MinValue) if you are not careful.
And you can use Nullable:
DateTime? date = null;
Which is nice and avoids most issues while introducing only 1 or 2.
It really depends on what you are trying to achieve.
You can set a DateTime variable to be '1/1/0001 00:00:00' but the variable itself cannot be null. To get this MinTime use:
DateTime variableName = DateTime.MinValue;
You may want to use a nullable datetime. Datetime? someDate = null;
You may find instances of people using DateTime.Max or DateTime.Min in such instances, but I highly doubt you want to do that. It leads to bugs with edge cases, code that's harder to read, etc.
The method you used (AddWithValue) doesn't convert null values to database nulls. You should use DBNull.Value instead:
myCommand.Parameters.AddWithValue(
"#SurgeryDate",
someDate == null ? DBNull.Value : (object)someDate
);
This will pass the someDate value if it is not null, or DBNull.Value otherwise. In this case correct value will be passed to the database.
Either:
DateTime dt = new DateTime();
or
DateTime dt = default(DateTime);
If you set the date to
DateTime dNewDate = new DateTime();
The value is set to {1/1/0001 12:00:00 AM}
Option 1: Use a nullable DateTime?
Option 2: Use DateTime.MinValue
Personally, I'd prefer option 1.
A string is a sequence of characters. So it makes sense to have an empty string, which is just an empty sequence of characters.
But DateTime is just a single value, so it's doesn't make sense to talk about an “empty” DateTime.
If you want to represent the concept of “no value”, that's represented as null in .Net. And if you want to use that with value types, you need to explicitly make them nullable. That means either using Nullable<DateTime>, or the equivalent DateTime?.
DateTime (just like all value types) also has a default value, that's assigned to uninitialized fields and you can also get it by new DateTime() or default(DateTime). But you probably don't want to use it, since it represents valid date: 1.1.0001 0:00:00.
There's no such thing as an empty date per se, do you mean something like:
DateTime? myDateTime = null;
The .addwithvalue needs dbnull.
You could do something like this:
DateTime? someDate = null;
//...
if (someDate == null)
myCommand.Parameters.AddWithValue("#SurgeryDate", DBnull.value);
or use a method extension...
public static class Extensions
{
public static SqlParameter AddWithNullValue(this SqlParameterCollection collection, string parameterName, object value)
{
if (value == null)
return collection.AddWithValue(parameterName, DBNull.Value);
else
return collection.AddWithValue(parameterName, value);
}
}
This will work for null able dateTime parameter
. .
SearchUsingDate(DateTime? StartDate, DateTime? EndDate){
DateTime LastDate;
if (EndDate != null)
{
LastDate = (DateTime)EndDate;
LastDate = LastDate.AddDays(1);
EndDate = LastDate;
}
}

why it throws an exception,if its same type date time

Am just trying to understand why this exception throws.
Cannot implicitly convert type 'System.DateTime?' to 'System.DateTime'. An explicit conversion exists (are you missing a cast?)
This is what am trying to do
story.BroadcastOn is a date time value am getting from database (eg: 23/03/2012 1:56 Pm).
Am trying to convert the time from 12 to 24 hrs format,this is what i was trying to do
DateTime testconverttime = story.BroadcastOn;`//this is where it throws exception
so i have to use the parse to get rid of this like below to solve my issue but it doesn't make sense to me
if (!string.IsNullOrEmpty(story.BroadcastOn.ToString()))
{
DateTime localTime = story.BroadcastOn.Value;//Thanks all for the great suggestion.
converttime = localTime.ToString("dd/MMM/yyyy HH:mm ", CultureInfo.CurrentCulture);
}
already i converted my 12 hrs to 24hrs but trying to understand the exception,some one will give me an explanation please.
DateTime testconverttime = story.BroadcastOn.Value;
It's a nullable type (can have the null state also)
A nullable value type (DateTime is a value type), has the concept of the null value (no value). So if for example a column of datetime in database has nulls, then you can use Nullable<DateTime> or in short DateTime? to store the values which comes from that column.
About DateTime.ToString() and String.ToDateTime(): this is called yo-yo programming. You probably saw with Debuger that there is a representation of valid DateTime, which was giving by calling ToString(), but, in future, don't try to cast a type to another type via this yo-yo technique.
Try this, assuming the nullable type has a value:
DateTime testconverttime = story.BroadcastOn.Value;
DateTime? and DateTime are not the same type. DateTime? is the nullable version of the DateTime type.
You should check whether it's null, and then either cast or retrieve the value of the nullable:
if (story.BroadcastOn.HasValue) {
var broadcastOn = story.BroadcastOn.Value;
// do stuff with broadcastOn
} else {
// handle null BroadcastOn
}
or
if (story.BroadcastOn != null) {
var broadcastOn = (DateTime) story.BroadcastOn;
// do stuff with broadcastOn
} else {
// handle null BroadcastOn
}
Using .HasValue or comparing with null, and using .Value and casting to the non-nullable type should be equivalent. You can also use the ?? operator.
Try casting it as a DateTime, like so:
DateTime testconverttime = (DateTime)story.BroadcastOn
System.DateTime? and System.DateTime are 2 different types. You need to use story.BroadcastOn.Value if you are sure if it is not null.
DateTime? and DateTime are not the same type so you can not implicitly assign DateTime? to DateTime
You need to either explicitly cast it or assign the value via the Value property of DateTime. However, if BroadcastOn is null, either method will throw an exception.
If you don't know BroadcastOn is not null then you best option to is use the null-coalescing operator:
DateTime dt = story.BroadcastOn ?? default(DateTime);

Categories