DateTime nil object exception blues

How can this result in a Nil Object Exception?

If fDT <> Nil Then mfileDateTime_copy = New dateTime( fDT ) // << I get NOE here End If

fDT is a dateTime - I can see its values in the debugger, it is not nil at this point, it points at folderItem.creationDateTime
mfileDateTime_copy is a dateTime property.

I don’t see a problem with that code, so I guess is something else. Can you create a small sample app that has the problem?

I just tried this in a new project, and it works as expected using 2019R3.1

var fDT as DateTime = DateTime.Now var mfileDateTime_copy as DateTime If fDT <> Nil Then mfileDateTime_copy = New dateTime( fDT ) // << I get NOE here End If

I’ve tried to distill out the problem but with no success. I think it is related to folderItem.creationDateTime and folderitem.modificationDateTime which seem to be problematic (at least for me).

For now I have done a work-around and saved the .totalSecondsSince1970 property rather than trying to make a copy of the fDT dateTime itself. This has solved this problem.

Yes, it was folderitem.creationDateTim (and probably modificationDateTime).

Dim f As FolderItem = folderitem.ShowOpenFileDialog("") If f = Nil Then Return Dim dt As dateTime = New dateTIme(f.CreationDateTime)

This gives Nil Object Exception on the last line.

What do you get if you do a f.creationdatetime.tostring ?

Following the docs this shouldn’t work, but it does:
change this code

Dim dt As dateTime  = New dateTIme(f.CreationDateTime)

to

Dim dt As dateTime = dateTIme(f.CreationDateTime)

I expected this code to work (docs)

Dim dt As New DateTime(f.CreationDateTime)

but it doesn’t work.

This is the code that I used for testing:

Var f As FolderItem = folderitem.ShowOpenFileDialog("") If f <> Nil Then Var dt As DateTime = DateTime(f.CreationDateTime) Label1.Value = dt.ToString(locale.current, DateTime.FormatStyles.Short) End If

I think this is just re-casting the dateTime rather than copying it which New DateTime(f.creationDateTime) is supposed to do.

All the other properties of f.creationDateTIme seem to be present and (with the exception of Timezone) correct.

This also works:

Var dt As DateTime = DateTime.FromString(f.CreationDateTime.SQLDateTime)

and

Var dt As DateTime = f.CreationDateTime

Except this doesn’t create a new instance.

Case reported

feedback://showreport?report_id=60839

I understand that Dim dt As dateTime = New dateTIme(f.CreationDateTime) should work because the docs only use DateTime.Now without using New before that Shared Method

Var d As DateTime = DateTime.Now

What I don’t understand is what you mean about ‘new instance’. Sorry about this. Can you explain what is that and how that could affect the code?

Yes, DateTIme is an object, not a primitive (like integers, text etc). So doing newDT = new DateTime(oldDT) creates a new object with the same property values as the old one. Whereas newDT = DateTime(oldDT) is simply making newDT the same object as oldDT.

Oh, thank you. I thought that DateTime being immutable we always get a new DateTime.

Immutable would mean that you can’t change it - i.e. its properties are all read-only.

In the case of DateTime you can add and or subtract intervals, so for example DT = DT + DI does create a new DateTime object.

DateTime.Now creates a new instance and returns it to you. That’s why you don’t need New in front of it. The New is inside the .Now function.

Immutable means that it acts like a new instance, when in fact it is not.

[quote=495505:@Tim Hare]DateTime.Now creates a new instance and returns it to you. That’s why you don’t need New in front of it. The New is inside the .Now function.

Immutable means that it acts like a new instance, when in fact it is not.[/quote]
DateTime.FromString creates a new instance too? Now that the case was closed as not reproducible (on a newer version of Xojo), I wonder what is the right approach to handle this until the next version of Xojo is released.

What problems could I get if I don’t create a new instance here? Is there a way to detect (debugger or something else) to know if the DateTime is a new instance when it is not? For example:

Var d1 As New DateTime(1956, 8, 13) Var d2 As DateTime = DateTime(d1)
instead of

Var d1 As New DateTime(1956, 8, 13) Var d2 As New DateTime(d1)

Dim d As datetime = datetime.now

Dim dt0 As datetime = d //just a pointer - same instance
Dim dt1 As dateTime = dateTIme(d) //re-casting - same instance
Dim dt2 As dateTime = New dateTIme(d) //new object - new instance
Dim dt3 As datetime = datetime.FromString(d.SQLDateTime) // via string - new instance

Yes.

You are pretty safe. Since you cannot change the DateTime object directly like you could with Date, pretty much anything you do to a DateTime will produce a new DateTime object and leave the other reference intact. That’s one of the reasons for creating the new class, to reduce the problems of having 2 variables pointing to the same object. With Date, you change one, the other reflects those changes. With DateTime, you change one, it gets assigned a new object and leaves the other alone.

Just don’t do this. It’s pointless. It is better to just write

var d2 as DateTime = d1

as that does exactly the same thing.