I had used AddDays(x) method before on DateTime objects and it was working fine but now my object is defined like this:
public DateTime? To_Date { get; set; }
And looks like this one does not have a AddDays method. How can I call it then?
Because DateTime? can be in a state representing null, you need to consider what to do if it's null.
The most obvious thing to do is to stay with a value of null (the day after null is null).
DateTime? later = ToDate.HasValue
? To_Date.Value.AddDays(numberOfDays)
: (DateTime?)null;
It maybe that there's some meaningful default date you can use, in which case:
DateTime later = (ToDate ?? defaultDate).AddDays(numberOfDays);
This will use defaultDate when ToDate has no value, and the value of ToDate otherwise.
You need to do To_Date.Value.AddDays(1);
To_Date refers to the wrapper which only has a couple of properties. One is a flag to indicate whether or not it's null, the other is the value itself. First check that it's not null, try to use AddDays on the value.
Try this:
To_Date.Value.AddDays(x);
Related
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
I'm looking to validate a DateTime variable to ensure that it isn't blank on the UI. The string equivalent checking would be String.IsNullOrEmpty(), but how would I go about it with my DateTime variable?
DateTime is a value type, so it cannot be null. To check if a DateTime variable has the default (all 0) value you can compare it with new DateTime() or default(DateTime).
Another option would be to use DateTime? instead of DateTime for user input and check HasValue property.
To check if a DateTime is null in C#, you must first ensure the DateTime is nullable.
// DateTime? means it is nullable
var DateTime? date = null;
// .HasValue only exists if DateTime is nullable
if(date.HasValue)
Console.WriteLine("date has a value");
else
Console.WriteLine("date is null");
If your DateTime is not nullable, make it nullable (unless you are absolutely certain in will never be null). You don't want to go down the road of assigning "nullish" values to your DateTimes. In my experience, this creates confusing bugs / code.
I am aware of the standard procedure for displaying a DateTime in a custom format, like so:
MessageBox.Show(dateSent.ToString("dd/MM/yyyy hh:mm:ss"));
However, when I change the variable from a DateTime to a DateTime? to accept null values, I lose the definition for the ToString(string) overload. I need to use DateTime? as I am reading from a database which potentially has null values - if the field in the database has a null value, then I need to assign the variable a null value too.
So I have two questions:
1) Out of curiosity, does anyone know if there is a reason why DateTime? does not contain an overload for ToString(string)?
2) Could anyone suggest an alternative method for what I am trying to achieve?
DateTime? is syntactic sugar for Nullable<DateTime> and that's why it don't have ToString(format) overload.
However, you can access underlying DateTime struct using Value property. But before that use HasValue to check, if the value exists.
MessageBox.Show(dateSent.HasValue ? dateSent.Value.ToString("dd/MM/yyyy hh:mm:ss") : string.Empty)
Instead of having to manually perform a null check every time, you can write an extension method.
public static string ToStringFormat(this DateTime? dt, string format)
{
if(dt.HasValue)
return dt.Value.ToString(format);
else
return "";
}
And use it like this (with whatever string format you want)
Console.WriteLine(myNullableDateTime.ToStringFormat("dd/MM/yyyy hh:mm:ss"));
You can still use
variableName.Value.ToString(customFormat);
DateTime? testDate = (DateTime?)arrayOfObjects[dateObject];
Does that code look ok? I attempted to use the as operator but I got the 'non-nullable' error. What I'm trying to say is that the object I'm choosing from the array is either DateTime or a null DateTime but either can be assigned to testDate.
Doesn't feel right doing it this way, I think I'm missing something obvious.
EDIT: I suppose it's the same as the way I could've adapted the as in the following way:
DateTime? testDate = arrayOfObjects[dateObject] as DateTime?;
Is either line of code the best way of handling potential nulls?
Is either line of code the best way of handling potential nulls?
The second form will silently result in null when the array contains something other than a DateTime. That seems a good reason to use the first.
To the basic question:
am I missing something or is this the typical (or at least an acceptable) approach
It is acceptable but a little obscure maybe, because it is 'hiding' an unboxing operation.
You could use:
DateTime? testDate = null;
if (arrayOfObjects[dateObject] != null)
testDate = (DateTime) arrayOfObjects[dateObject]; // no '?'
But that's verbose. And this particular problem doesn't lend itself well to the conditional operator (?:)
So I would stick with your first version.
DateTime? is a shorter form for another struct
Nullable<DateTime> {
bool HasValue;
DateTime Value;
}
You will never get this type from your DB, so the first line will never cast correctly. The database will provide you with a DateTime value stored in an object variable. Or a null (untyped).
DateTime is a struct, so "as" operator won't work for it. So, simply check for null as follows:
DateTime? testDate = arrayOfObjects[dateObject] == null ? (DateTime?) null : (DateTime)arrayOfObjects[dateObject];
A better approach would be to do something like:
if(arrayOfObjects[dateObject] != null && arrayOfObjects[dateObject] is DateTime)
{
DateTime testDate = (DateTime)arrayOfObjects[dateObject];
// logic here
}
or something like:
DateTime? testDate = null;
if(arrayOfObjects[dateObject] is DateTime)
{
testDate = (DateTime)arrayOfObjects[dateObject];
}
else if (arrayOfObjects[dateObject] is Nullable<DateTime>)
{
testDate = (Nullable<DateTime>)arrayOfObjects[dateObject];
}
Try using Array.ConvertAll method. Below is roughly how it is implemented:
DateTime?[] dates = Array.ConvertAll<object, DateTime?>arrayOfObjects,DateTime);
Note: This is just a rough idea. you can correct it to suit your self.
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;
}
}