Wednesday, May 21, 2014

Getting dates and calculating a time interval in C# - Part I

I wanted to create a console app in Visual C# which required the app to choose a path based on the number of days elapsed between the current date and a date entered by the user. I assumed I would do a quick search and find a way to do this on MSDN or Stack Overflow. I assumed many people had done this many times and code snippets would be posted all over the web. Wrong. Sure, I found a way to subtract one date from another if I entered the dates as arguments or the app was a form. But I couldn't find a way to do it when 1) the app was a console app, 2) the app provided the current date and 2) the user entered another date which would be subtracted from the current date.

This is a two-part post explaining the program I wrote to resolve the problem. Part I explains how to get the dates. The second part will explain how to subtract the dates to get the time interval. The full source code is on GitHub.

Today is the day
Getting today's date is easy:

     Console.WriteLine("Today's date is {0}.", DateTime.Today);

Microsoft has already provided us with the DateTime struct and its property, Today. By reviewing the source code, you can see that Today is a static property.  Static properties can be called without an object being created, hence, the reason the code snippet above will display the current date and time.

However, for my purposes, there are a couple of problems with this code. First, this format will give you a time of 12:00:00 AM as well as the date. For my app, I didn't need the time. Second, I didn't need to merely display the current date, I needed to store it so that another date could be subtracted from it. As painfully obvious as this is now, I wasn't sure how to do that. If you aren't either, read on.

Construct Today
Starting with the basics, DateTime is structure (a.k.a. struct) in the System namespace. You do not need to use keyword "new" to instantiate a struct object. Create the object like so to display only the date:

     DateTime dateOnly = DateTime.Today;
     Console.WriteLine("Today's date is {0}.", dateOnly.ToString("d");

     (The "d" is a short date format specifier. In other words, this format will give you the date and not the time.)

You may also want to read DotNetPerls which explains why you would choose the Today property over the Now property.

User Input
Since DateTime is a struct, that means it is a type. After I ask the user to input a date, I declare a DateTime variable and convert the line entered by the user to DateTime type. Just as with the code snippet above, though, this will display the date and a time. So the next step is to create a DateTime object and use the short date format specifier in the Console.WriteLine argument.

         Console.WriteLine("Enter the date you bought your vehicle.");
         Console.WriteLine("Use this format, 01/01/2011.");
         DateTime whenBought = Convert.ToDateTime(Console.ReadLine());
         DateTime boughtDateOnly = whenBought.Date;
         Console.WriteLine("Vehicle was bought on {0}.", boughtDateOnly.ToString("d"));

Here is a screen shot of the output.


The next post will go over TimeSpan and its Subtract method.

Sunday, May 11, 2014

Optional Parameters and Named Parameters in C#

I just don't like it when simple things are explained in a complex manner. So let me break it down for other C# noobs, in case you have a textbook like mine that provides an insufficient explanation or if you just don't understand these two types of parameters.

Optional Parameters

You will be surprised to learn that, as the name suggests, this means the parameters* are optional. The client code does NOT have to provide arguments for these parameters. Why? Because a default value is already included for you.

Example: public void optParam (int x, int y =2, int z = 3)
                       {some code};//this method has two optional parameters

In this case, there are two optional parameters, "y" and "z". Parameter "y" has a default value of 2 and parameter "z" has a default value of 3. If no value is provided for "y" or "z", they will retain their default values. You will notice that parameter "x" has no default value provided. This means that the client code MUST provide an argument for this parameter. Also be aware that the required parameter must come before the optional parameters.

Obviously, there is a problem. If you want to provide an argument for "z" and not for "y", how can you make the arguments be evaluated so that the first argument will be applied to "x" and the second argument to "z"? You can't. As MSDN informs us, you would have no choice but to specify the argument for the optional parameter "y" before providing the argument for "z". Needless to say, there would be no point in having an optional parameter "y" in that case. This is where named parameters come to the rescue.

*Per MSDN, optional and named parameters can be used with methods, constructors, indexers and delegates.

Named Parameters

When calling the method, the client code need only name the optional parameters for which it wishes to provide a value, avoiding the problem just described.

Example:  public void optParam (int x, int y =2, int z = 3) {some code};
                optParam (20, z: 30);

This result is x = 20, y =2 and z = 30. You avoid having to rewrite the default value and another benefit is that you can put the named parameters in any order. The same rule about required parameters coming before optional parameters applies here. The arguments supplied for the optional parameters can come in any order as to each other, but they must come after the arguments for the required parameters.

Example:  public void optParam (int x, int y =2, int z = 3, int zz = 5) {some code};
                optParam (20, zz: 30, y: 10);//okay
                optParam (y: 30, zz: 10, 20);//not okay

Here you can see a sample of code I wrote to show how the two types of parameters work together and a screen shot of the results: https://github.com/htravar/Parameters. You may also find this article helpful.

This topic does get more complex, but I hope I've explained the basics in a basic way. Enjoy the parameter shortcut.