Date DataType Vs. DateTime Structure Vs. DateAndTime - vb.net

I found that there can be 5 different ways of declaring a date in VB.Net. They are:
Dim date_one As Date = #2021-3-31#: This is one of the allowed formats of date literals in VB
Dim date_two As New Date(2021,3,31) : Initializes an instance of the DateTime structure to the year, month and day
Dim date_three As DateTime : Declaring a DateTime Value to its default value
Dim date_four As New DateTime() : Calling parameterless constructor - sets to default value
Dim date_five As New DateTime(2021, 3, 31) : Supplying parameters to the constructor
My confusion /questions w.r.t to the above are the following:
A. DateTime is a structure in the system namespace. We do not use NEW keyword to declare a structure type variable. So why then in points 2,4,5 are we allowed to use the NEW keyword?
B. In point 2, we declare the type as DATE whereas in 3,4,5 we declare the type as DateTime. Infact if we compare2 & 5 then we see that they are doing exactly the same thing with the difference being tht one is declared as DATE and the other as DateTime. So my question is What is the difference between DATE and DateTime? If there is no difference why do we have two different words for the same thing?
C. Point 1 is a VB.Net language specific syntax for a date literal. This means I cant use this syntax in another .NET language. But the dates defined in points 2,3,4 and 5 make use of the DateTime structure which is in the system namespace and therefore this way of declaring or constructing dates is allowed in other .Net languages. ----> Is this understanding correct?
D. I also came across a class named DateAndTime. This belongs to the Microsoft.VisualBasic namespace and I believe that is reason this class is exclusive to VB.Net. Since it doesnt belong to the system namespace We cant import it in another .Net language --- Is this understanding correct?
E. Finally, how to decide whether to to use DATE or DateTime? Also when should we use DateAndTime Class? What advantage/limitation does each of them provide?
Would be grateful to anyone willing to help,
Regards,
Sougata

A. Class fields (variables at class level) and local variables (i.e., variables declared in methods or property getters and setters) get initialized to their default value if there is no initializer and there is no initialization code in the class constructor (for fields). So, a New is not required if you are happy with the default value.
Note that a Date (or DateTime) is a Structure and therefore a value type. Default values of value types are "real" values in contrast to reference types (Classes) having a default value of Nothing, meaning that no object is assigned to this variable. This is also called a null reference. (In fact you can assign Nothing to a value type; however, this will translate to a value like 0, False, #1/1/0001 12:00:00 AM#, etc.)
You must differentiate between declaring fields or variables and initializing them. To declare means to give them a name and a type. Initialize means assigning them value for the first time.
You can do this with two statements
Dim d As Date 'Declare
d = New Date(2021, 3, 30) 'Initialize
or use an initializer
Dim d As Date = New Date(2021, 3, 30) 'Declare and initialize
These two variants are equivalent. The first one allows you to assign a value later, the second one is more compact.
B. The .NET Framework defines primitive types and gives them a name in the System Namespace. E.g., System.String, System.Int32 or System.DateTime. Visual Basic gives many of them an alias. For the previously listed types those are String, Integer and Date. C# gives them the different aliases, string, int and has no alias for the DateTime.
The framework name and the corresponding Visual Basic (or C#) aliases are totally equivalent. System.Int32 ≡ VB Integer ≡ C# int.
C. Yes, e.g., in C# you must write new System.DateTime(...) (of course you can always import the namespace and omit the System. prefix). The Visual Basic date literal is just a short form for New Date(...) or New System.DateTime(...).
D. The DateAndTime Class is in fact a Visual Basic module. It is called class, because C# has no notion of modules as in VB and instead implements them as static classes.
The documentation says:
The DateAndTime module contains the procedures and properties used in date and time operations.
Languages in the .NET Framework have a Common Type System. Therefore, you can use a type defined in one language in all the other .NET languages. Also, the generated code is compatible, so you can share methods as well.
E. In Visual Basic I would use the aliases. It makes the code more concise.
You are using the DateAndTime automatically when you write for instance
Dim d As Date = Now
Now is declared in this module. DateAndTime does not compete with Date or DateTime, as you cannot use it to declare variables, i.e., DateAndTime is not a type.
See also:
Date Data Type (Visual Basic)
Value Types and Reference Types
Data Type Summary (Visual Basic)
Data type (Wikipedia)

A. DateTime is a structure in the system namespace. We do not use NEW keyword to declare a structure type variable. So why then in points 2,4,5 are we allowed to use the NEW keyword?
Structures may have constructors
B. In point 2, we declare the type as DATE whereas in 3,4,5 we declare the type as DateTime. Infact if we compare2 & 5 then we see that they are doing exactly the same thing with the difference being tht one is declared as DATE and the other as DateTime. So my question is What is the difference between DATE and DateTime? If there is no difference why do we have two different words for the same thing?
see https://stackoverflow.com/questions/5625795/date-instead-of-datetime
C. Point 1 is a VB.Net language specific syntax for a date literal. This means I cant use this syntax in another .NET language. But the dates defined in points 2,3,4 and 5 make use of the DateTime structure which is in the system namespace and therefore this way of declaring or constructing dates is allowed in other .Net languages. ----> Is this understanding correct?
The data type IS the same across .Net regardless of how it comes to be.
D. I also came across a class named DateAndTime. This belongs to the Microsoft.VisualBasic namespace and I believe that is reason this class is exclusive to VB.Net. Since it doesnt belong to the system namespace We cant import it in another .Net language --- Is this understanding correct?
If the .Net language allows you to import the Microsoft.VisualBasic namespace you can probably use it. Would NOT suggest it.
E. Finally, how to decide whether to to use DATE or DateTime? Also when should we use DateAndTime Class? What advantage/limitation does each of them provide?
Hmmmm.... DateAndTime does have some different date calculations that can be useful.
My preference is to use DateTime.
If all I'm interested in is the Date or Time then I reference that.
Dim d1 As Date = Date.Now
Dim d2 As DateTime = DateTime.Now
If d1 = d2 Then
Stop
End If
If d1.Date = d2.Date Then
Stop
End If
If d1.TimeOfDay = d2.TimeOfDay Then
Stop
End If
A lot of these questions can be answered by searching the documentation.

Related

Structure where the data type of a member differs

Maybe superfluous, but some intro...
I am rewriting an add-in for my CAD-application (using VB.NET).
This add-in reads, via an API, a bunch of metadata from a file, presents it in a Form. This data can then be (partially) changed and written back to the file.
This metadata is accessible in a consistent way, however the data type is not the same everywhere (String, Currency, Date, Boolean, Long and IPictureDisp).
Currently I have a much too complex class with several arrays. I thought it might be smarter to create a structure. The problem is the varying data type.
Is it possible to define a structure with a member with varying datat type, or am I forced to define a different structure for each data type?
You have a few options...
1: Use Object
Nice and simple, every data type inherits from Object - so if your struct contains a property of type Object, you can put pretty much any data type in there
From the docs:
The Object data type can point to data of any data type, including any object instance your application recognizes. Use Object when you do not know at compile time what data type the variable might point to.
However, this does mean that you will get next to no help from the compiler when you are trying to write code using this property. You will also probably have to cast any time you need to do anything type-specific
2: Generic Types
This will not fit situations where you are not sure of the type. You can create a generic struct using the Of syntax.
You'd create it as so:
Structure MyStructure(Of T)
'our changing type
Dim MyCustomData As T
'...alongside regular types
Dim Name As String
Dim OtherThing As Integer
End Structure
and then when you need to create the structure, you'd simply pass the type in and assign the value
Dim struct As New MyStructure(Of Integer)
struct.MyCustomData = 123
Dim struct2 As New MyStructure(Of String)
struct2.MyCustomData = "a"

How can I create an "enum" type property value dynamically

I need to create a property in a class that will give the programmer a list of values to choose from. I have done this in the past using the enums type.
Public Enum FileType
Sales
SalesOldType
End Enum
Public Property ServiceID() As enFileType
Get
Return m_enFileType
End Get
Set(ByVal value As enenFileType)
m_enFileType = value
End Set
End Property
The problem is I would like to populate the list of values on init of the class based on SQL table values. From what I have read it is not possible to create the enums on the fly since they are basically constants.
Is there a way I can accomplish my goal possibly using list or dictionary types?
OR any other method that may work.
I don't know if this will answer your question, but its just my opinion on the matter. I like enums, mostly because they are convenient for me, the programmer. This is just because when I am writing code, using and enum over a constant value gives me not only auto-complete when typing, but also the the compile time error checking that makes sure I can only give valid enum values. However, enums just don't work for run-time defined values, since, like you say, there are compile time defined constants.
Typically, when I use flexible values that are load from an SQL Table like in your example, I'll just use string values. So I would just store Sales and SalesOldType in the table and use them for the value of FileType. I usually use strings and not integers, just because strings are human readable if I'm looking at data tables while debugging something.
Now, you can do a bit of a hybrid, allowing the values to be stored and come from the table, but defining commonly used values as constants in code, sorta like this:
Public Class FileTypeConstants
public const Sales = "Sales"
public const SalesOldType = "SalesOldType"
End Class
That way you can make sure when coding with common values, a small string typo in one spot doesn't cause a bug in your program.
Also, as a side note, I write code for and application that is deployed internally to our company via click-once deployment, so for seldom added values, I will still use an enum because its extremely easy to add a value and push out an update. So the question of using and enum versus database values can be one of how easy it is to get updates to your users. If you seldom update, database values are probably best, if you update often and the updates are not done by users, then enums can still work just as well.
Hope some of that helps you!
If the values aren't going to change after the code is compiled, then it sounds like the best option is to simply auto-generate the code. For instance, you could write a simple application that does something like this:
Public Shared Sub Main()
Dim builder As New StringBuilder()
builder.AppendLine("' Auto-generated code. Don't touch!! Any changes will be automatically overwritten.")
builder.AppendLine("Public Enum FileType")
For Each pair As KeyValuePair(Of String, Integer) In GetFileTypesFromDb()
builder.AppendLine(String.Format(" {0} = {1}", pair.Key, pair.Value))
End For
builder.AppendLine("End Enum")
File.WriteAllText("FileTypes.vb", builder.ToString())
End Sub
Public Function GetFileTypesFromDb() As Dictionary(Of String, Integer)
'...
End Function
Then, you could add that application as a pre-build step in your project so that it automatically runs each time you compile your main application.

Struts 1 ActionForms - What's the convention for dates in the form?

I am about to start with e project that uses Struts 1.2. There is no plan to move to another framework.
I wanted to know what's the convention when handling a date in the form?
Should I create a Date variable and create a setDate(String date) method where the conversion will occur?
Create a Date variable, a setDate(Date date) and register a special converter somewhere in the chain? (don't know if it's possible)
Create a String variable, a setDate(String date) and let the conversion/validation to the validate method in the ActionForm bean?
Or another approach?
Also, if you have any advice to get up to speed with this framework, I would really appreciate it.
Before I respond to your question, let me start by saying this: People don't understand what ActionForm is or what ActionForm does
The ActionForm represents the data that the user filled in the HTML form. Struts reads in the request parameters and matches them by name with the configured ActionForm for the target Action of the submit. It is data inputted by the user, plain and simple.
Data that comes on the request is always of type java.lang.String. But people might have a form field named "age" which is an int in their Model data. Or maybe instead of "age" they have a "birthDate" which off course is java.util.Date in their Model data. So they think it is a good idea to have the type int and Date placed on the ActionForm and allow Struts to convert the Strings that arrive on request into ints and Dates.
Its a very useful conversion and you as a developer don't have to handle it, Struts does. It's a little bit of framework magic.
But this ain't freaking Harry Potter! Conversion can fail on ints and Dates. Why?
int is a primitive type and as such it must always have a value. Default initialization is with zero. When doing the binding (request parameters to ActionForm object properties) Struts sees an int type on the ActionForm and tries to convert the request String value to int.
If user inserted String "5", the field is set to 5. That's fine!
But what if user inserted "bla"? Will we get an exception thrown in our face? Nope! We get back a value of zero because conversion (silently) failed. Ups!
Dates again are an issue. Why? Because their value arrives on request as String. Their format might be something simple like "12/01/2011" which is completely useless as information. Why? Because Dates represented as Strings must go hand in hand with a Locale in order to be transformed to the correct Date instance it represents.
"12/01/2011" + Locale.US = 01 December 2011
"12/01/2011" + Locale.FRENCH = 12 January 2011
Ups!
Ok, so this was the intro! Now let's go to your question.
Should I create a Date variable and create a setDate(String date) method where the conversion will occur.
At some point you will have to send the Date back to the view and the Struts html tags will normally have to go for a getDate() which returns String. The "12/01/2011" you get on user input might be displayed as "Jan. 12, 2011 00:00:00" if the getter returns Date (Struts will do a toString() on the getter value). So you actually need the Date field with both a setter/getter of type Date and a setter/getter of type String. Use type Date in your Action class and use String for interfacing with the view tags.
Question? How do you get handle on the proper Locale value in your ActionForm?
Create a Date variable, a setDate(Date date) and register a special converter somewhere in the chain (don't know if it's possible)
It is possible. You can create and register a custom converter that might take String representations of dates and convert them to Date. If you use the ISO 8601 format I think you will be safe.
Question? Can you accommodate this into the existing application without breaking code that transforms String to dates in their own way by using all sorts of formats or Locales?
Create a String variable, a setDate(String date) and let the conversion/validation to the validate method in the actionForm bean
This won't work. The validate method is called after the parameter bindings on the ActionForm object. When you reach this point is already to late. Struts did the conversion. If you have a field of type int with value zero there is no way to know if the user actually inserted zero and conversion worked or if the user inserted "bla" and the conversion failed and you got back zero as default initialization value. If zero is a valid value for your application than you are in even bigger trouble.
So what's the convention?
There is no convention. Use the above information and apply common sense given your situation.
Ideally you should have all properties in the ActionForm as Strings so that you loose no information during the binding. But this involves manually converting the properties to the proper type in the Action class, before using them. You have full control (Struts no longer does conversions since source and destination values are of type String) but you also have a lot of boiler plate code to write to do it the proper way which at some point can become annoying.
P.S. Before I end this and go to bed (it's 01:00 AM in my Country :D) I just want to mention one thing that people often don't see. The ActionForm is not part of the model, neither should it interact directly with the model.
If you need the data from the ActionForm to be processed in the model, then map it as a one-to-one relationships with a Model DTO (data transfer object). If you don't, then you create a tight coupling between the Model and the Struts framework because your ActionForm objects are not a POJOs. Your class must extend the ActionForm class from Struts that we've been talking about. People don't do this and send the ActionForm straight to the Model. What is even worse is that they also use the validate method to perform business validations instead of basic validation such as "is required", "is value withing range" etc.
ActionForms are just a communication path between the Action (controller) and the view. Treat it as such.

Determining if a type is a reference type or value type

I've come from a Assembler and C/C++ background, so I understand the concept behind reference types versus value types in vb.net. Also, I've read Jon Skeet's article regarding references and value types and I understand all of that.
My question is: How can you tell if a given type is a reference type or a value type?
Is it simply that all integral types (ints, floats, etc.) are value types and all classes are reference types? (If so, where do strings fall?)
Question 2 (related): Is there a way to declare a class as a value class versus a reference class? For example (using extreme brevity):
Public Class MyClass1
Public Value As Integer
End Class
Using this class:
Dim test1 As New MyClass1
test1.Value = 1
Dim test2 As MyClass1
test2 = test1
test2.Value = 2
At the end of this code, the Value in Test1 is 2. Clearly, MyClass1 is a reference type. But, what is it that causes it to be such and not a value type?
In general - enums and structs are value types, classes interfaces and delegates are reference types.
As for declaring a class as a value type - this is not possible, but C# structs are very close to classes and are value types.
As for VB.NET, I believe the equivalent is the Structure statement:
The Structure statement defines a composite value type that you can customize.

Creating a function that uses a generic structure?

I am attempting to create a generic function that the students in my introductory VB .NET course can use to search a single dimension array of a structure.
My structure and array look like this:
Private Structure Survey
Dim idInteger As Integer
Dim membersInteger As Integer
Dim incomeInteger As Integer
Dim stateString As String
Dim belowPovertyLevelBoolean As Boolean
End Structure
Private incomeSurvey(199) As Survey
My generic function header looks like:
Private Function FindSurveyItem(Of xType As Structure)
(ByVal surveyIDInInt As Integer, ByVal surveyArrayIn() As xType) As Integer
??????
End Function
My call to the function looks like:
If FindSurveyItem(Of Survey)(CInt(idTextBox.Text), incomeSurvey) <> -1 Then
My question is: Is there a way to reference the individual structure fields in the array from inside the function? I was trying to make it generic so that the student could simply pass their array into the function - their structure may be named differently than mine and the field names may be different.
I suspect there are other ways to deal with this situation, but I was trying to keep it to just a simple single-dimension array of a structure. I don't think it is possible to do what I want, but I wondered what others thought.
Is there a way to reference the individual structure fields in the array from inside the function?
Generic instead of an array you need a collection type. Add LINQ Code:
Dim Surveys = From svys In xType
Where svys.idInteger = surveyIDInInt
Select svys
For Each rSurveys In svys
'''' Your Code
Next
This is rough answer fill in the details (I know imagine LINQ without SQL DB!!)
If you have a genric type parameter T you are only able to access members of instances of T that are known to exist at compile time. As every type derives from Object you have only the members of Object availiable - ToString(), GetType(), GetHashCode(), and Equals().
If you want to access other members you have to constrain what T is allowed to be. In your situation a interface would be the way to go. See MSDN for details.
You could also try to use reflection or check the actual type at runtime an perform a cast. The first is hard to impossible to do if you do not know much about the types you will get. And the later requires you to know possible types at compiletime and will not work in your situation, too.
Another way might be to pass a delegate to the search method that performs the actual comparison.
What you're looking for are predicates, if using ,net 3.5
dim arr() as structure
Array.Find(arr, function(item)(item.MyMember = MemberToMatch))
More combersome in earlier versions, see here for more info
The point being, that your function would look very like an implementation of Array.Find (if you didn't want to use the function provided), and the students would need to write their own predicate function.
No, there isn't. You can't know the type at compile time, therefore you cannot access members of that type. You would need change from a structure to a class that must implement IComparable so that you can use CompareTo between the item you pass in and the array you are passing in.
Though it's not entirely clear what you are trying to do within your method so I'm guessing by the name of the method.
You can use reflection to get those fields, but in this case that wouldn't have much meaning. How would you know that the passed type has the field you're looking for? There are other problems with that code as well.
Instead, to do this I would normally create an interface for something like this that had a public ID property, and constrain my input to the function to implement that interface, or as others mentioned use a built-in feature in the clr.
But that may be ahead of where your students are. If you just want an example of a generic function, my suggestion is to show them a type-safe implementation of the old vb imediate if function:
Public Function IIf(Of T)(ByVal Expression As Boolean, ByVal TruePart As T, ByVal FalsePart As T) AS T
If Expression Then Return TruePart Else Return FalsePart
End Function
Note that this is obsolete, too, as in VS2008 and beyond you can use the new If operator instead, which will work better with type inference and won't try to evaluate the expression that isn't returned.