How to pass null as DateTime value? - datetime

In a database, there is a field that saves a closure date. This date can be NOT NULL only if the case has been closed. If the case is not closed, it has to be NULL. How can I pass null value to a DateTime object?
Tried this but it doesn't work.
DateTime closure= dateDatumIspisa.SelectedDate ?? null;
DateTime closure= dateDatumIspisa.SelectedDate ?? DateTime.Parse("");
DateTime closure= dateDatumIspisa.SelectedDate ?? DBNull.Value;
DateTime closure= dateDatumIspisa.SelectedDate ?? DateTime.Parse(DBNull.Value.ToString());
Also tried GetValueOrDefault() but it inserts DateTime.Min value, while I need this field left empty.
Any suggestions?

Just make closure a DateTime? instead of a DateTime. The whole point of Nullable<T> is to make a nullable type from a non-nullable one.
Now, you haven't shown the type of SelectedDate - but if it's already a DateTime? then you don't need to use ?? at all. Just:
DateTime? closure= dateDatumIspisa.SelectedDate;
How familiar are you with nullable value types in general? You might want to read up on the MSDN coverage of them.

Declare
DateTime ? closure = dateDatumIspisa.SelectedDate;
no need here to use the ?? in this line !

Related

Symfony2, Doctrine, How set datetime to Entity

i can not understand how can i persist datetime to database. I have string
(string) $oXml->currentTime
actually it's not a string but we convert it, so how can i add it to entity without error
Fatal error: Call to a member function format() on a non-object in...
current code
$currentTime = \DateTime::createFromFormat('Y-m-d H:m:s', (string) $oXml->currentTime);
$cachedUntil = \DateTime::createFromFormat('Y-m-d H:m:s', (string) $oXml->cachedUntil);
$oApiKeyInfo
->setCurrentTime($currentTime)
->setCachedUntil($cachedUntil)
not working :(
You need to pass the a DateTime object. Create it with a new statement, you can specify the time to use with the first constructor parameter.
$currentTime = new \DateTime((string) $oXml->currentTime);
$cachedUntil = new \DateTime((string) $oXml->cachedUntil);
$oApiKeyInfo->setCurrentTime($currentTime)
->setCachedUntil($cachedUntil);
If you need to specify a Timezone you can use the DateTimeZone class and pass it as the second parameter to the DateTime constructor.

Set default display value for Symfony2 form field

I've got a form with some display only fields in it. These fields are usually DateTime values... but when empty/null I would like to display the string "never".
EDIT:
To be more explicit: The field should show the DateTime value from the database and if null the string 'never' should be displayed.
How should I do that?
Thanks in advance
You can use Symfony2 Data Transformers :
In the transform() function you can check if your date is null and then return the 'never' string. Otherwise return a string representation of your date.
In the reverseTransform() function you can check if the string is 'never' and then construct a null DateTime object. Otherwise, you transform the given string into a valid DateTime object with something like 'strtotime()` PHP function.

Can I cast a string object passed on command line argument to the actual object?

Is it possible to cast a command-line passed string object back to actual object?
I want to do the following, but throwing error can't cast.
Button objPro = (Button) sender;
cProduct cp = (cProduct) objPro.CommandArgument;
If no, then why?
This is what the string holds.
cProduct cpObj = (cProduct)e.Row.DataItem;
Button btnAddProduct = (Button)e.Row.FindControl("btnAddProduct");
if (btnAddProduct != null)
{
btnAddProduct.CommandArgument = cpObj.ToString();
}
You probably can't, because it's a string. It's not a cProduct (whatever that is - consider following .NET naming conventions and naming it Product instead).
Now you could do this if you had a explicit conversion operator in cProduct to create an instance from a string.
You haven't really explained what's in the string, or what's in the type - but if your cProduct type provides a ToString method which contains all the data in a reversible form, then you could easily write a method or a constructor to create the product again:
Product product = new Product(objPro.CommandArgument);
or maybe:
Product product = Product.Parse(objPro.CommandArgument);
You'll have to write that constructor/method, of course.
I would strongly recommend using a constructor or method instead of an operator, just to keep your code clearer - it's very rarely a good idea to write your own conversion operators.
Take a look at CommandArgument on MSDN. The property is a string, when you assign the a value to the property, you aren't casting some complex type to string, you are setting a string value on the property. Can you cast a string back to your object type anyway, regardless of it being a CommandArgument. I doubt it. If the argument is an int you could try int.Parse or similar for other types which have a parse method.

Out-of-range Datetime issue using LINQtoSQL

Here is a snippet of my model:
* SQL Server *
Event
-----
Id (int, PK) NOT NULL
Title (varchar(100)) NULL
LastModified (datetime) NULL
EventDates
----------
Id (int, PK) NOT NULL
StartDate (datetime) NULL
EndDate (datetime) NULL
* C# *
Event
-----
public int Id
public string Title
public DateTime LastModified
EventDates
----------
public int Id
public DateTime StartDate
public Datetime EndDate
The LastModified field has been in the database since its creation. I have been saving it's value when I save an event, but I want to display it in a table, so I changed up my Event repository's GetEvents's return value:
return (from e in GetDbEvents()
select new Event
{
// Miscellaneous fields..
LastModified = e.LastModified.GetValueOrDefault() // Shiny new code
});
When I call this now, I get yelled at:
The conversion of a char data type to a datetime data type
resulted in an out-of-range datetime value.
If I strip down the above code to this, it still doesn't help and I get the same error if I attempt to enumerate over the result:
var test = (from e in _db.Events
select e.LastModified.GetValueOrDefault());
As a test, I did the same statement for my EventDates table (again, with 2 datetime columns):
var test4 = (from ed in _db.EventDates
select new EventDate
{
StartDate = ed.StartDate.GetValueOrDefault(),
EndDate = ed.EndDate.GetValueOrDefault()
});
This works fine, of course. No errors when I enumerate, all values are correct.
I should point out that some LastModified values in the Events table are NULL while all values in EventDates are populated with data.
Edit
My main question is why does Events give me out-of-range issues and EventDates does not, even though the model is quite similar?
The problem is with the GetValueOrDefault(). This will return DateTime.MinValue (01-01-0001) in the "default" case and sqlserver doesn't accept that (it refuses dates before about 1753).
If you use a Nullable<DateTime>, then sql will be happy with the null it will get.
If you change the declaration of your C# variable LastModified to public DateTime? LastModified that should fix your problem. The addition of the question mark indicates that it is a nullable type.
Perhaps this is related?
One possible fix (if you don't want to change LastModified to DateTime?, requiring you to litter your code with .Value everywhere..) would be to get the values from the Database as DateTime?'s, but translate them to DateTime's in your code. For example:
return from e in GetDbEvents()
select new Event(e.LastModified);
...
//In Event class:
public Event(DateTime? lastModified)
{
LastModified = lastModified.GetValueOrDefault();
}
This will cause GetValueOrDefault() to be called client-side, rather than being part of the SQL.
Note that this approach does have problems of its own...
To expand on Hans Kesting's answer, and help people who encounter this issue in a filtering/WHERE clause rather than in the SELECT clause:
The problem is with the GetValueOrDefault() call. LINQ to SQL (somewhat stupidly IMO) translates this to real SQL by using a COALESCE clause (similar to ISNULL) like this:
COALESCE(LastModified, '1/1/0001 12:00:00 AM')
Unfortunately, the SQL Server datetime data type doesn't accept dates before about 1753. So SQL Server throws the error back to LINQ to SQL, which throws it back to you.
If you use a Nullable, then SQL Server will be happy with the null it will get. But if you still want to use GetValueOrDefault(), e.g. in a query to filter the results you have a couple options:
LastModified.GetValueOrDefault(System.Data.SqlTypes.SqlDateTime.MinValue.Value)
LastModified.HasValue && LastModified > DateTime.Now

ConvertEmptyStringToNull=”false” and yet the conversion still happens

DetailsView is bound to ObjectDataSource. Inside Detailsview’s EditItemTemplate are two TextBoxes ( T1 and T2 ). T1 is mapped to update parameter of type String, while T2 is mapped to update parameter of type DateTime.
Assuming both TextBoxes contain an empty string, then when I try to update the data source by clicking on DetailsView’s Update button, ODS ( or is it perhaps DetailsView ) automatically converts T1’s empty string to null, while T2’s empty string doesn’t get converted to null. I’ve tried to prevent ODS from converting T1’s empty string to null by setting T1’s update parameter’s ConvertEmptyStringToNull property to false ( I ‘ve also set <asp:TemplateField ConvertEmptyStringToNull=”false” …>, but to no effect.
a)Any idea why T1’s empty string gets converted, while T2’s doesn’t?
b) Also, how can I prevent the conversion( BTW - I realize I could convert null back to empty string inside update method )?
thanx
a)Any idea why T1’s empty string gets
converted, while T2’s doesn’t?
T2 is a DateTime which is a value type. Value types can't be null. Well unless you use the Nullable type
b) Also, how can I prevent the
conversion( BTW - I realize I could
convert null back to empty string
inside update method )?
EDIT: I've tried to duplicate the problem above, but I could only duplicate the problem when I didn't specify ConvertEmptyStringToNull="false" in the <asp:TemplateField> of the bound control AND the <asp:Parameter> of the <asp:ObjectDataSource>. If you leave either out then you will get the null value on an empty field. With the ConvertEmptyStringToNull="false" defined in both places it does not convert the empty string to a null value. The empty string is passed correctly. You said that you did try it in both places, so I'm not sure why it's not working for you. Maybe you could show us your datasource and detailsview markup.
With that said I think it is still a good idea to make the check described below in your business class. Like you said you can convert null back to an empty string. This is how I have done it:
I have a helper class, lets call it BizObject, that contains this method:
protected static string ConvertNullToEmptyString(string input)
{
return (input == null ? "" : input);
}
Then in my business class's Insert/Update method I call ConvertNullToEmptyString on each string parameter:
public static bool UpdateSource(string sourceName, DateTime sourceDate)
{
sourceName = BizObject.ConvertNullToEmptyString(sourceName);
...
bool ret = UpdateSource(record);
return ret;
}

Resources