Combining Date and Time

The Current Date and Time

When a user starts a computer and while using it, it keeps a date and time values referred to as local date and time or system date and time. Depending on your application, at one time you may need to get one or both of these pieces of information. It is important to know that the computer, not you, controls this information (but you can programmatically change it if you want). To support both, the DateTime structure is equipped with a static property named Now. This property holds the year, the month, the day, the name of the day, the hour, the minute, and the second. Here is an example of accessing it:

WriteLine(string.Format("System Date and Time: {0}", DateTime.Now));
        WriteLine("============================================");

Here is an example of running the program:

System Date and Time: 9/10/2020 10:18:41 PM
============================================
Press any key to continue . . .

To get the current date of the computer, the DateTime structure provides a static property named Today. Here is an example:

WriteLine(string.Format("Current Date: {0}", DateTime.Today));
        WriteLine("====================================");

Here is an example of running the program:

Current Date: 9/10/2020 12:00:00 AM
====================================
Press any key to continue . . .

Formatting Date and Time Combinations

Although the DateTime structure is equipped to produce default values of a date and time in combination, you can use the formats we have reviewed to create your own date, in the sequences of your choice, such as a time preceding a date, a value providing only the month and the minutes, etc.

Windows Controls: A Timer

Introduction

A timer is a non-spatial object that uses recurring lapses of time in a computer or in your application. To work, every lapse of period, the control sends a message to the operating system. The message is something to the effect of "I have counted the number of lapses you asked me to count".

As opposed to the time that controls your computer, a timer is partly but greatly under your control. Users do not see nor do they use a timer as a control. As a programmer, you decide if, why, when, and how to use this control.

To support timers, the .NET Framework provides a class named Timer. You can use that class to programmatically create a timer. To let you visually add a timer to your application, the Toolbox is equipped with a button named Timer. It is available in the Components section of the Toolbox. You can click that control and click your form. The timer is not a visual control. Therefore, if you visually add it to your form, it would only be represented by a button below the form.

Characteristics of a Timer

A timer is an object used to count lapses of time and send a message when it has finished counting. Each count is called a tick. When a tick occurs, the control fires an event named Tick. This Tick event is of type EventArgs, meaning that it doesn't provide more information than to let you know that a lapse has occurred. Here is an example of implementing that event:

using System.Drawing;
using System.Windows.Forms;

 : Form
{
    Timer tmrFlash;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        tmrFlash = new  Timer ();
        tmrFlash.Tick += new EventHandler(btnFlashTick);

        Text = "Text Flasher";
        Size = new System.Drawing.Size(435, 88);
    }

    void btnFlashTick(object sender, EventArgs e)
    {
    }
}

public class Program
{
    static int Main()
    {
        Application.Run(new Exercise());
        return 0;
    }
}

The amount of time allocated for counting is called an interval and it is represented by the Interval property. The Interval property is a very important characteristic of the Timer control because it measures and controls the total time needed to perform a complete count. The Interval is measured in milliseconds. Like any counter, the lower the value, the faster the count, and the higher the value, the longer the count. The amount of interval you specify will depend on what you are trying to do. Here is an example of specifying the interval:

void InitializeComponent()
{
    tmrFlash = new  Timer ();
    tmrFlash.Interval = 500;
    tmrFlash.Tick += new EventHandler(btnFlashTick);
}

In order for a timer to count, you must tell it when it should start counting. In some applications, you may want the control to work full-time while in some other applications, you may want the control to work only in response to an intermediate event. The ability to stop and start a Timer control can be set using a Boolean property named Enabled. Here is an example of enabling a timer:

using System.Drawing;
using System.Windows.Forms;

 : Form
{
    Timer tmrFlash;
    Label lblFlash;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        tmrFlash = new  Timer();
        tmrFlash.Interval = 500;
        tmrFlash.Enabled = true;
        tmrFlash.Tick += new EventHandler(btnFlashTick);

        lblFlash = new Label();
        lblFlash.AutoSize = true;
        lblFlash.Text = "C# Programming is Fun!!!";
        lblFlash.Font = new System.Drawing.Font("Square721 BT", 24F);
        lblFlash.ForeColor = System.Drawing.Color.Blue;
        lblFlash.Location = new System.Drawing.Point(12, 10);

        Text = "Text Flasher";
        Size = new System.Drawing.Size(435, 88);
        Controls.Add(lblFlash);
    }

    void btnFlashTick(object sender, EventArgs e)
    {
        if (lblFlash.Text == "C# Programming is Fun!!!")
            lblFlash.Text = "";
        else
            lblFlash.Text = "C# Programming is Fun!!!";
    }
}

public class Program
{
    static int Main()
    {
        Application.Run(new Exercise());
        return 0;
    }
}

When, or as soon as, this property is set to true, the control starts counting. You can also make it start by calling the Timer.Start() method. Its syntax is:

public void Start();

If, when, or as soon as, the Enabled property is set to false, the control stops and resets its counter to 0. You can also stop the timer by calling the Timer.Stop() method. Its syntax is:

public void Stop();

Introductory Topics on Time Values

The Time of Day of a Time Value

As seen so far, a DateTime variable always holds both a date and a time portions. In your design, you may want to get only the time of the variable. To support this, the DateTime structure is equipped with a property named TimeOfDay. This property produces the time value of an existing DateTime object. Here is an example of using it:




{
    
    {
        Title = "Time Values";

        DateTime time = new DateTime(2002, 4, 22, 16, 8, 44);

        WriteLine("Date and Time: {0}", time);
        WriteLine($"Time of Day:   {time.TimeOfDay}");
        WriteLine("===================================");
        return 10;
    }
}

This would produce:

Date and Time: 4/22/2002 4:08:44 PM
Time of Day:   16:08:44
===================================
Press any key to continue . . .

Retrieving a Time Value

In a certain application, you may want the visitor to provide a time value. A valid time can follow the format hh:nn AM/PM or hh:nn:ss or one of the valid combinations. When requesting a time from the user, in case the user is not familiar with the rules (and you should assume that the user doesn't know them), specify what formula the user should follow.

To get the hour portion of an existing DateTime object, you can access its Hour property. To retrieve the minute side of a time value, access its Minute property. If you want to know the second value of a DateTime variable, you can call its Second property. In the same way, you can get the millisecond value of a time by accessing its Millisecond property.

Windows Controls and Dates Values

Introduction

You ahould always make sure your graphical application is as user-friendly. When it comes to date values, you should make sure to assist your users so they can provide only valid values, and in the previous lesson, we saw that date values most follow strict rules. To assist you, the .NET Framework provides various Windows controls specially made for date values, making it practically impossible for the user to provide invalid date values.

Labels and Text Boxes

As you may know already, the label and the text box are the primary Windows controls used in an application. They are also the vaguest controls because they can deal with almost any value. When it comes to a date, if you are requesting such a value, in the caption of the label, you can include the format you want the user to use. Here is an example:

Labels and Text Boxes

The Calendar Windows Control

Introduction

The calendar is a Windows control that presents a calendar on a form and allows the user to select a date:

Modeling a Window

Creating a Calendar

To support the calendar control, the .NET Frameworok provides a class named MonthCalendar. To add a calendar to your application, in the Toolbox, click MonthCalendar and click the form. The characteristics of the control can be managed through the MonthCalendar class. Those characteristics can be visually accessed in the Properties window.

Selecting a Date

A calendar control displays the days of a selected month. The control also displays the remaining days, if any, of the first week of the currently selected month; that is, the days of the previous month that share the week with the first day of the first week of the selected month. The control also displays the first days of the subsequent month that share the week with the last day of the current month.

To use the calendar control, the user can click a date, whether a date from the current month or a day of the other (previous and next) month. To support the date selected on the calendar, the MonthCalendar class is equipped with a property named SelectionStart.

When the user has clicked a date to select it, the control fires a DateSelected event. The DateSelected event is of type DateRangeEventArgs.

You too can programmatically select a date on the calendar control. To do this, assign a valid DateTime value to both the SelectionStart and the SelectionEnd properties.

Practical LearningPractical Learning: Introducing Operations on Date Values

  1. Start Microsoft Visual Studio and create a Windows Forms application named GasUtilityCompany3
  2. On the main menu, click Project -> Add New Item...
  3. In the left list, under Visual C# Items, click Code
  4. In the middle list, click Interface
  5. Change the file name to UtilityMeter
  6. Press Enter
  7. Change the document as follows:
    namespace GasUtilityCompany3
    {
        public interface IUtilityMeter
        {
            string MeterNumber { get; set; }
            string Make        { get; set; }
            string Model       { get; set; }
        }
    }
  8. In the Solution Explorer, right-click GasUtilityCompany3 -> Add -> Class...
  9. Change the file Name to GasMeter
  10. Click Add
  11. Change the document as follows:
    using System;
    
    namespace GasUtilityCompany31
    {
        public class GasMeter : IUtilityMeter
        {
            public string   MeterNumber  { get; set; }
            public string   Make         { get; set; }
            public string   Model        { get; set; }
            public int      CounterValue { get; set; }
        }
    }
  12. In the Solution Explorer, right-click GasUtilityCompany3 -> Add -> Class...
  13. Change the file name to Customer
  14. Click Add
  15. Change the class as follows:
    namespace GasUtilityCompany3
    {
        public class Customer
        {
            public string AccountNumber { get; set; }
            public string MeterNumber   { get; set; }
            public string FirstName     { get; set; }
            public string LastName      { get; set; }
            public string Address       { get; set; }
            public string City          { get; set; }
            public string County        { get; set; }
            public string State         { get; set; }
            public string ZIPCode       { get; set; }
        }
    }
  16. On the main menu, click Window -> Form1.cs [Design]
  17. Complete the design of the form as follows:

    Introducing the Calendar Control

    Control (Name) Text Other Properties
    Label   Customer Account Information

    BackColor: Gray
    ForeColor: White

    Label   Account #:  
    TextBox txtAccountNumber    
    Label   Customer Name:  
    TextBox txtCustomerName    
    Label   Address  
    TextBox txtAddress    
    TextBox txtCity    
    TextBox txtCounty    
    TextBox txtState    
    TextBox txtZIPCode    
    Label   Meter Information

    BackColor: Gray
    ForeColor: White

    Label   Meter Details:  
    TextBox txtMeterNumber    
    TextBox txtMeterDetails    
    Label   Meter Reading  
    Label   _________________________  
    Label   Counter Reading Start:  
    TextBox txtCounterReadingStart   TextAlign: Right
    Label   Counter Reading End:  
    TextBox txtCounterReadingEnd   TextAlign: Right
  18. On the form, click the Account # text box
  19. In the Properties window, click the Events button Events
  20. Double-click Leave
  21. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany32
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                /* This is the list of utility meters used by the company.
                 * Every device has a unique meter number. */
                meters = new GasMeter[]
                {
                    new GasMeter() { MeterNumber = "582741-38", Make = "Sinton International", Model = "D-244",    CounterValue =   138 },
                    new GasMeter() { MeterNumber = "293847-27", Make = "Archimeda",            Model = "LP2066",   CounterValue =  2866 },
                    new GasMeter() { MeterNumber = "928731-59", Make = "EnvioSmart",           Model = "84-D9703", CounterValue =  8016 },
                    new GasMeter() { MeterNumber = "520246-85", Make = "Garland Worldwide",    Model = "GFH-2260", CounterValue = 22683 },
                    new GasMeter() { MeterNumber = "797047-27", Make = "Archimeda",            Model = "LP2066",   CounterValue =   725 },
                    new GasMeter() { MeterNumber = "425837-14", Make = "EnvioSmart",           Model = "28-G4428", CounterValue =  6114 },
                    new GasMeter() { MeterNumber = "162460-82", Make = "Archimeda",            Model = "Di8000",   CounterValue = 15502 },
                    new GasMeter() { MeterNumber = "864085-92", Make = "Sinton International", Model = "D-244",    CounterValue =    83 }
                };
    
                /* This si the list of customers who use the gas produced and distributed by the company.
                 * Every customer uses a utility metter number. That number must (1) correspond to a gas 
                 * meter from the above list, (2) the gas meter a customer uses must be unique among the other customers. */
                customers = new Customer[]
                {
                    new Customer(){ AccountNumber = "620-9720-824", MeterNumber = "293847-27", FirstName = "Jefferey",    LastName = "Parriot", Address = "688 Gorman Str",     City = "Rockville",   County = "Montgomery",    State = "MD", ZIPCode = "20856" },
                    new Customer(){ AccountNumber = "4482-1397-851", MeterNumber = "425837-14", FirstName = "Christopher", LastName = "McGee",   Address = "3316 Sanderson Rd",  City = "Alexandria",  County = "",              State = "VA", ZIPCode = "22312" },
                    new Customer(){ AccountNumber = "852-9360-597", MeterNumber = "582741-38", FirstName = "Sandra",      LastName = "Rhodes",  Address = "11158 Grattos Ave",  City = "Hyattsville", County = "Prince George", State = "MD", ZIPCode = "20783" },
                    new Customer(){ AccountNumber = "209-5384-805", MeterNumber = "928731-59", FirstName = "Marco",       LastName = "Ramos",   Address = "9012 Jefferson Crt", City = "Washington",  County = "",              State = "DC", ZIPCode = "20012" },
                    new Customer(){ AccountNumber = "972-3848-393", MeterNumber = "797047-27", FirstName = "Gabrielle",   LastName = "Bayley",  Address = "799 Boomerang Str",  City = "Columbia",    County = "Howard",        State = "MD", ZIPCode = "21042" }
                };
    
                // Request/Get the customer's account number from the user 
                string acntNbr = txtAccountNumber.Text;
    
                // We will need to identify the gas meter that a customer is using.
                string striMeterNumber = string.Empty;
    
                // When the user has typed a customer's account number, visit each of the customers accounts.
                for (int i = 0; i <= customers.Length - 1; i++)
                {
                    // Find out if there is a customer record that has the accont number the user had entered.
                    if (customers[i].AccountNumber == acntNbr)
                    {
                        // If the user entered a valid customer's account, display the information of that customer
                        txtCustomerName.Text = string.Format("{0}, {1}", customers[i].LastName, customers[i].FirstName);
                        txtAddress.Text = customers[i].Address;
                        txtCity.Text = customers[i].City;
                        txtCounty.Text = customers[i].County;
                        txtState.Text = customers[i].State;
                        txtZIPCode.Text = customers[i].ZIPCode;
    
                        // Get the gas meter number the user is using
                        striMeterNumber = customers[i].MeterNumber;
    
                        // Since you found the customer record, stop looking
                        break;
                    }
                }
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        // Since you found the customer's gas meter, stop looking
                        break;
                    }
                }
            }
        }
    }
  22. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Introducing Operations on Date Values

  23. Click the Account # text box and type an account number, such as 620-9720-824

    Modeling a Window

  24. Press Tab:

    Modeling a Window

  25. Close the form and return to your programming environment
  26. On the main menu, click Window -> Form1.cs [Design]

Practical LearningPractical Learning: Introducing the Calendar Control

  1. On the Toolbox, under Common Controls, click MonthCalendar
  2. Click an unoccuped area of the form
  3. Once again, on the Toolbox, click MonthCalendar and click the form
  4. Complete the design of the form as follows:

    Introducing the Calendar Control

    Control (Name) Text
    Label   Reading Start Date
    Label   Reading End Date
    MonthCalendar mcReadingStartDate  
    MonthCalendar mcReadingEndDate  
  5. Click the GasMeter.cs tab and add a new property as follows:
    using System;
    
    namespace GasUtilityCompany32
    {
        class GasMeter :IUtilityMeter
        {
            public string   MeterNumber      { get; set; }
            public string   Make             { get; set; }
            public string   Model            { get; set; }
            public DateTime MeterReadingDate { get; set; }
            public int      CounterValue     { get; set; }
        }
    }

Practical LearningPractical Learning: Selecting a Date

  1. Click the Form1.cs tab and change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany31
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                /* This is the list of utility meters used by the company.
                 * Every device has a unique meter number. */
                meters = new GasMeter[]
                {
                    new GasMeter() { MeterNumber = "582741-38", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021,  5, 10), CounterValue =   138 },
                    new GasMeter() { MeterNumber = "293847-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021,  8, 3), CounterValue =  2866 },
                    new GasMeter() { MeterNumber = "928731-59", Make = "EnvioSmart",           Model = "84-D9703", MeterReadingDate = new DateTime(2020, 12, 8), CounterValue =  8016 },
                    new GasMeter() { MeterNumber = "520246-85", Make = "Garland Worldwide",    Model = "GFH-2260", MeterReadingDate = new DateTime(2021, 5, 21), CounterValue = 22683 },
                    new GasMeter() { MeterNumber = "797047-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021, 10, 4), CounterValue =   725 },
                    new GasMeter() { MeterNumber = "425837-14", Make = "EnvioSmart",           Model = "28-G4428", MeterReadingDate = new DateTime(2021,  1, 1), CounterValue =  6114 },
                    new GasMeter() { MeterNumber = "162460-82", Make = "Archimeda",            Model = "Di8000",   MeterReadingDate = new DateTime(2020,  6, 3), CounterValue = 15502 },
                    new GasMeter() { MeterNumber = "864085-92", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021, 10, 5), CounterValue =    83 }
                };
    
                /* This si the list of customers who use the gas produced and distributed by the company.
                 * Every customer uses a utility metter number. That number must (1) correspond to a gas 
                 * meter from the above list, (2) the gas meter a customer uses must be unique among the other customers. */
                customers = new Customer[]
                {
                    new Customer(){ AccountNumber = "620-9720-824", MeterNumber = "293847-27", FirstName = "Jefferey",    LastName = "Parriot", Address = "688 Gorman Str",     City = "Rockville",   County = "Montgomery",    State = "MD", ZIPCode = "20856" },
                    new Customer(){ AccountNumber = "482-1397-851", MeterNumber = "425837-14", FirstName = "Christopher", LastName = "McGee",   Address = "3316 Sanderson Rd",  City = "Alexandria",  County = "",              State = "VA", ZIPCode = "22312" },
                    new Customer(){ AccountNumber = "852-9360-597", MeterNumber = "582741-38", FirstName = "Sandra",      LastName = "Rhodes",  Address = "11158 Grattos Ave",  City = "Hyattsville", County = "Prince George", State = "MD", ZIPCode = "20783" },
                    new Customer(){ AccountNumber = "209-5384-805", MeterNumber = "928731-59", FirstName = "Marco",       LastName = "Ramos",   Address = "9012 Jefferson Crt", City = "Washington",  County = "",              State = "DC", ZIPCode = "20012" },
                    new Customer(){ AccountNumber = "972-3848-393", MeterNumber = "797047-27", FirstName = "Gabrielle",   LastName = "Bayley",  Address = "799 Boomerang Str",  City = "Columbia",    County = "Howard",        State = "MD", ZIPCode = "21042" }
                };
    
                // Request the customer's account number from the user 
                string acntNbr = txtAccountNumber.Text;
    
                // We will need to identify the gas meter that a customer is using.
                string striMeterNumber = string.Empty;
    
                // When the user has typed a customer's account number, visit each of the customers accounts.
                for (int i = 0; i <= customers.Length - 1; i++)
                {
                    // Find out if there is a customer record that has the accont number the user had entered.
                    if (customers[i].AccountNumber == acntNbr)
                    {
                        // If the user entered a valid customer's account, display the information of that customer
                        txtCustomerName.Text = string.Format("{0}, {1}", customers[i].LastName, customers[i].FirstName);
                        txtAddress.Text = customers[i].Address;
                        txtCity.Text = customers[i].City;
                        txtCounty.Text = customers[i].County;
                        txtState.Text = customers[i].State;
                        txtZIPCode.Text = customers[i].ZIPCode;
    
                        // Get the gas meter number the user is using
                        striMeterNumber = customers[i].MeterNumber;
    
                        break;
                    }
                }
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        
                        mcReadingStartDate.SelectionStart = meters[i].MeterReadingDate;
    
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        break;
                    }
                }
            }
        }
    }
  2. To execute the project, on the main menu, click Debug -> Start Without Debugging

    Selecting a Date

  3. Click the Account text box if necessary. Type 482-1397-851 and press Enter:

    Selecting a Date

  4. Close the for and return to your programming environment
  5. In the Solution Explorer, double-click Form1.cs to access the form
  6. Complete the design of the form as follows:

    Selecting a Date

    Control (Name) Text Other Properties
    Label   Customer Account Information

    BackColor: Gray
    ForeColor: White

    Label   Account #:  
    TextBox txtAccountNumber    
    Label   Customer Name:  
    TextBox txtCustomerName    
    Label   Address  
    TextBox txtAddress    
    TextBox txtCity    
    TextBox txtCounty    
    TextBox txtState    
    TextBox txtZIPCode    
    Label   Meter Information

    BackColor: Gray
    ForeColor: White

    Label   Meter Details:  
    TextBox txtMeterNumber    
    TextBox txtMeterDetails    
    Label   Meter Reading  
    Label   _________________________  
    Label   Reading Start Date  
    Label   Reading End Date  
    MonthCalendar mcReadingStartDate    
    MonthCalendar mcReadingEndDate    
    Label   Counter Reading Start:  
    TextBox txtCounterReadingStart   TextAlign: Right
    Label   Counter Reading End:  
    TextBox txtCounterReadingEnd   TextAlign: Right
    Label   Number of Days:  
    TextBox txtNumberOfDays    
    Label   CCF Total:  
    TextBox txtCCFTotal   TextAlign: Right
    Label   Total Therms (CCF * 1.0367):  
    TextBox txtTotalTherms   TextAlign: Right
    Label   Bill Values

    BackColor: Gray
    ForeColor: White

    Label   Transportation Charges:  
    TextBox txtTransportationCharges   TextAlign: Right
    Label   Delivery Total:  
    TextBox txtDeliveryTotal   TextAlign: Right
    Label   Distrib. Adjust (*0.13086):  
    TextBox txtDistributionAdjustment   TextAlign: Right
    Label   Environmental Charges:  
    TextBox txtEnvironmentalCharges   TextAlign: Right
    Label   First 50 Therms (* 0.5269):  
    TextBox txtFirst50Therms   TextAlign: Right
    Label   Over 50 Therms (* 0.4995):  
    TextBox txtOver50Therms   TextAlign: Right
    Label   Local/County Taxes:  
    TextBox txtLocalTaxes   TextAlign: Right
    Label   State Taxes:  
    TextBox txtStateTaxes   TextAlign: Right
    Label   Total Charges:  
    TextBox txtTotalCharges   TextAlign: Right
    Label   __________________  
    Label   Payment Due Date:  
    TextBox txtPaymentDueDate   TextAlign: Right
    Label   Amount Due:  
    TextBox txtAmountDue   TextAlign: Right
  7. On the form, click the Counter Reading End text box
  8. In the Properties window, click the Events button Events
  9. Double-click Leave
  10. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany3
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                /* This is the list of utility meters used by the company.
                 * Every device has a unique meter number. */
                meters = new GasMeter[]
                {
                    new GasMeter() { MeterNumber = "582741-38", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021,  5, 10), CounterValue =   138 },
                    new GasMeter() { MeterNumber = "293847-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021,  8, 3), CounterValue =  2866 },
                    new GasMeter() { MeterNumber = "928731-59", Make = "EnvioSmart",           Model = "84-D9703", MeterReadingDate = new DateTime(2020, 12, 8), CounterValue =  8016 },
                    new GasMeter() { MeterNumber = "520246-85", Make = "Garland Worldwide",    Model = "GFH-2260", MeterReadingDate = new DateTime(2021, 5, 22), CounterValue = 22683 },
                    new GasMeter() { MeterNumber = "797047-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021, 10, 4), CounterValue =   725 },
                    new GasMeter() { MeterNumber = "425837-14", Make = "EnvioSmart",           Model = "28-G4428", MeterReadingDate = new DateTime(2021,  1, 1), CounterValue =  6114 },
                    new GasMeter() { MeterNumber = "162460-82", Make = "Archimeda",            Model = "Di8000",   MeterReadingDate = new DateTime(2020,  6, 3), CounterValue = 15502 },
                    new GasMeter() { MeterNumber = "864085-92", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021, 10, 5), CounterValue =    83 }
                };
    
                /* This si the list of customers who use the gas produced and distributed by the company.
                 * Every customer uses a utility metter number. That number must (1) correspond to a gas 
                 * meter from the above list, (2) the gas meter a customer uses must be unique among the other customers. */
                customers = new Customer[]
                {
                    new Customer(){ AccountNumber = "620-9720-824", MeterNumber = "293847-27", FirstName = "Jefferey",    LastName = "Parriot", Address = "688 Gorman Str",     City = "Rockville",   County = "Montgomery",    State = "MD", ZIPCode = "20856" },
                    new Customer(){ AccountNumber = "482-1397-851", MeterNumber = "425837-14", FirstName = "Christopher", LastName = "McGee",   Address = "3316 Sanderson Rd",  City = "Alexandria",  County = "",              State = "VA", ZIPCode = "22312" },
                    new Customer(){ AccountNumber = "852-9360-597", MeterNumber = "582741-38", FirstName = "Sandra",      LastName = "Rhodes",  Address = "11158 Grattos Ave",  City = "Hyattsville", County = "Prince George", State = "MD", ZIPCode = "20783" },
                    new Customer(){ AccountNumber = "209-5384-805", MeterNumber = "928731-59", FirstName = "Marco",       LastName = "Ramos",   Address = "9012 Jefferson Crt", City = "Washington",  County = "",              State = "DC", ZIPCode = "20012" },
                    new Customer(){ AccountNumber = "972-3848-393", MeterNumber = "797047-27", FirstName = "Gabrielle",   LastName = "Bayley",  Address = "799 Boomerang Str",  City = "Columbia",    County = "Howard",        State = "MD", ZIPCode = "21042" }
                };
    
                // Request the customer's account number from the user 
                string acntNbr = txtAccountNumber.Text;
    
                // We will need to identify the gas meter that a customer is using.
                string striMeterNumber = string.Empty;
    
                // When the user has typed a customer's account number, visit each of the customers accounts.
                for (int i = 0; i <= customers.Length - 1; i++)
                {
                    // Find out if there is a customer record that has the accont number the user had entered.
                    if (customers[i].AccountNumber == acntNbr)
                    {
                        // If the user entered a valid customer's account, display the information of that customer
                        txtCustomerName.Text = string.Format("{0}, {1}", customers[i].LastName, customers[i].FirstName);
                        txtAddress.Text = customers[i].Address;
                        txtCity.Text = customers[i].City;
                        txtCounty.Text = customers[i].County;
                        txtState.Text = customers[i].State;
                        txtZIPCode.Text = customers[i].ZIPCode;
    
                        mcReadingStartDate.SelectionStart = meters[i].MeterReadingDate;
    
                        // Get the gas meter number the user is using
                        striMeterNumber = customers[i].MeterNumber;
    
                        // Since you found the customer record, stop looking
                        break;
                    }
                }
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        // Since you found the customer's gas meter, stop looking
                        break;
                    }
                }
            }
    
            private void txtCounterReadingEnd_Leave(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtAccountNumber.Text))
                {
                    MessageBox.Show("You must enter the starting value of the counter reading.",
                                    "Quatro Gas Company");
                    return;
                }
    
                if (string.IsNullOrEmpty(txtMeterNumber.Text))
                {
                    MessageBox.Show("You must enter the meter number of the gas meter used by " +
                                    "the customer (normally, this is done by entering the customer's account number).",
                                    "Quatro Gas Company");
                    return;
                }
    
                if (string.IsNullOrEmpty(txtCounterReadingEnd.Text))
                {
                    MessageBox.Show("You must enter the ending value of the counter reading.",
                                    "Quatro Gas Company");
                    return;
                }
    
                int meterReadingStart = int.Parse(txtCounterReadingStart.Text);
                int meterReadingEnd = int.Parse(txtCounterReadingEnd.Text);
    
                int consumption = meterReadingEnd - meterReadingStart;
    
                double totalTherms = consumption * 1.0367;
                double first50Therms, over50Therms;
    
                if (totalTherms < 50)
                {
                    first50Therms = totalTherms * 0.5269;
                    over50Therms = 0;
                }
                else
                {
                    first50Therms = 50 * 0.5269;
                    over50Therms = (totalTherms - 50) * 0.4995;
                }
    
                /* We will use some random values for the transportation charge (my 
                 * research didn't make it clear to me how gas companies set this price. */
                Random   rndTransportation    = new Random();
                double[] transportationValues = { 9.75, 9.95, 10.25, 10.45, 10.85, 12.55, 13.50, 14.35 };
    
                double transportationCharges = transportationValues[rndTransportation.Next(1, transportationValues.Length)];
                double deliveryTotal = transportationCharges + first50Therms + over50Therms;
    
                double distribution = totalTherms * 0.11086;
                double environment = deliveryTotal * 0.0045;
                double state = transportationCharges * 0.0225;
                double local = transportationCharges * 0.05826;
                double totalCharges = transportationCharges + deliveryTotal + distribution + environment + local + state;
                double amtDue = totalCharges;
    
                txtStateTaxes.Text = state.ToString("F");
                txtLocalTaxes.Text = local.ToString("F");
                txtAmountDue.Text = amtDue.ToString("F");
                txtCCFTotal.Text = consumption.ToString();
                txtTotalTherms.Text = totalTherms.ToString("F");
                txtOver50Therms.Text = over50Therms.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtFirst50Therms.Text = first50Therms.ToString("F");
                txtDeliveryTotal.Text = deliveryTotal.ToString("F");
                txtEnvironmentalCharges.Text = environment.ToString("F");
                txtDistributionAdjustment.Text = distribution.ToString("F");
                txtLatePaymentAmountDue.Text = (amtDue + 8.35).ToString("F");
                txtTransportationCharges.Text = transportationCharges.ToString("F");
            }
        }
    }
  11. To execute the project, on the main menu, click Debug -> Start Without Debugging

    Selecting a Date

  12. In the Account # text box, type an account number, such as 852-9360-597 and press Tab:

    Selecting a Date

  13. Click the Dounter Reading End text box and type 266

    Selecting a Date

  14. Press Tab:

    Selecting a Date

  15. Close the form and return to your programming environment

The Date Changed Event

When a date has been selected, whether by the user (using the mouse or the keyboard) or by you (through code), the control fires a DateChanged event. The DateChanged event is of type DateRangeEventArgs.

The DateRangeEventArgs class is equipped with two properties: Start and End. When the user clicks a date, these two properties hold the date that was clicked. This means that you can use either of these properties to know the date that was clicked. Both the Start and the End properties are of type DateTime.

Practical LearningPractical Learning: Introducing the Calendar Control

  1. Click the Form1 [Design] tab to display the form
  2. On the form, double-click the Reading End Date month calendar to initiate its DateChanged event

The Date Picker

Introduction

Like the calendar, the date picker is a control that allows the user to select a date value:

Date Picker

Date/Time Picker

 

To support the date-picker, the .NET Framework provides a class named DateTimePicker. You can declare a variable for it and initialize it using the new operator. Here is an example:

using System.Drawing;
using System.Windows.Forms;

 : System.Windows.Forms.Form
{
    DateTimePicker dtpDataHired;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        dtpDataHired = new DateTimePicker();
        dtpDataHired.Location = new Point(12, 12);
    }
}

To visually add a date/time picker to a form or other container, in the Common Controls section of the Toolbox, click DateTimePicker DateTimePicker and click the host. The date/time picker control can be considered as two controls in one: you just have to choose which one of both controls you want to use.

After adding the date/time picker control to the form, to allow the user to set the dates and not the times on the control, set its Format property either to Long (the default) or to Short. Here is an example:

using System.Drawing;
using System.Windows.Forms;

 : System.Windows.Forms.Form
{
    DateTimePicker dtpDataHired;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        dtpDataHired = new DateTimePicker();
        dtpDataHired.Location = new Point(12, 12);
        dtpDataHired.Format = DateTimePickerFormat.Long;
    }
}
Date Picker

Characteristics of the Date Picker

The Spin Button

After adding a date time picker control and setting its Format to either Long (the default) or Short, the control becomes a combo box (the default). If you do not like the combo box, you can display a spin button instead. This characteristic is controlled by the ShowUpDown Boolean property. When its value is set to False (the default), the control appears as a combo box. It you set it to True, it appears as a spin button:

Date Picker


If the control displays a combo box and if the user clicks the arrow on the Date control, a calendar object similar to the month calendar control displays:

Date Picker

The Check Box

In some cases, you may want to decide when to allow the user to select a date or when to disable it. There are two ways you can do this. You can use the Control's Enabled property that all other controls inherit. Another technique you can use is to display a check box on the left side of the text box section of the control. The presence or absence of the check box is controlled by the ShowCheckBox Boolean property whose default value is False. If you set it to True, a check box appears:

Date Picker: ShowCheckBox Effect

When the check box is checked, the user can change the displayed date. When the check box is unchecked, the control is displayed and the user cannot change the date. The user must first put a check mark in the check box in order to be able to change the date.

The state of the check box is controlled by the Boolean Checked property. If the user clicks the check box to put a check mark in it, this property's value becomes true. 

Using the Date Picker

As its name indicates, the date picker either displays a date or it allows the user to specify a date. The control follows the format of the date values specified in the regional settings of Control Panel. Consequently, the date is made of various sections including the name of the day, the name of the month, the numeric day in the month, and the year.

If the control is equipped with a spin button, to change the month, the user can click the month and then click one of the arrow buttons of the spin control. The user can also use the arrow keys to get the same effect. In the same way, the user can change the values of the day or the year.

If the control appears as a combo box, the user can click the arrow button. This would display a calendar:

Date Picker

When the calendar displays, the control fires an event named DropDown. The DropDown event is of type EventArgs. This means that this event does not carry any significant information, other than to let you know that the calendar of the control has been dropped to display.

While the calendar is displaying, the user can change the month, change the year, or click a date to select one. The user can still change the date in the text box side of the control. However it is done, on the text box or on the calendar, when the date of the control has been changed, the control fires an event named ValueChanged. The ValueChanged event, which is the default event of the control, is of type EventArgs, meaning it doesn't give you any detail about the date that was selected or about anything the user did. You would use your own means of finding out what date the user had selected or specified. This can easily be done by getting the Value property of the control.

If the control is displaying a calendar, once the user clicks a date, the calendar disappears and the control becomes a combo box again. When the calendar retracts, the control fires an event named CloseUp. The CloseUp event is of type EventArgs, which means it doesn't carry any particular information other than letting you know that the calendar has been closed.

The Minimum and the Maximum Dates

If you want to control the range of dates the user can select, use the MinDate and the MaxDate properties as we mentioned them from the MonthCalendar control. Here is an example:

using System.Drawing;
using System.Windows.Forms;

 : System.Windows.Forms.Form
{
    DateTimePicker dtpDataHired;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        dtpDataHired = new DateTimePicker();
        dtpDataHired.Location = new Point(12, 12);
        dtpDataHired.MinDate = new DateTime(2000, 1, 1);
    }
}

The Value of the Calendar

When you add the date picker control to your form or container, it displays the date of the computer on the day (or night) the control was added. If you want the control to display a different date, set the desired value in the Value field of the Properties window. At any time, you can find out what value the Date Picker has by retrieving the value of the Value property.

The Custom Format of the Calendar

If you set the Format property to Long, the date displays using the Long Date format of Control Panel. If you set the Format to Short, the control uses the Short Date value of Control Panel. If you want to customize the way the date is displayed, set the Format property to Custom. After setting the Format to Custom, use the CustomFormat property to create the desired format. The format is created by combining the following characters:

Format Used For Description
d Days Displays the day as a number from 1 to 31
dd Days Displays the day as a number with a leading 0 if the number is less than 10
ddd Weekdays Displays a weekday name with 3 letters as Mon, Tue, etc
dddd Weekdays Displays the complete name of a week day as Monday, etc
M Months Displays the numeric month from 1 to 12
MM Months Displays the numeric month with a leading 0 if the number is less than 10
MMM Months Displays the short name of the month as Jan, Feb, Mar, etc
MMMM Months Displays the complete name of the month as January, etc
yy Years Displays two digits for the year as 00 for 2000 or 03 for 2003
yyyy Years Displays the numeric year with 4 digits

Here is an example:

using System.Drawing;
using System.Windows.Forms;

 : System.Windows.Forms.Form
{
    DateTimePicker dtpDataHired;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        dtpDataHired = new DateTimePicker();
        dtpDataHired.Location = new Point(12, 12);
        dtpDataHired.Format = DateTimePickerFormat.Custom;
        dtpDataHired.CustomFormat = "dd MMMM yyyy";
    }
}
Date Picker

This means that you should be reluctant to let the users type whatever they want. The less they type, the less checking you need to do.

Accessories for Dates Operations

Introduction

Like value types and strings, dates support various types of operations. These include adding a value to a date to get a new date, subtracting a value from a date, extracting a certain value from a date, etc.

The Leap Year

A leap year is a year in which the month of February has 29 days. To let you find out whether a year is a leap year, the DateTime structure is equipped with a static method named IsLeapYear. The syntax of this method is:

public static bool IsLeapYear(int year);

This method takes an integer argument and examines it. If the argument, which must be a valid year number, is a leap year, the method returns true; otherwise, it returns false. Here are two examples:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime date1 = new DateTime(1988, 10, 6);
        DateTime date2 = new DateTime(1990, 8, 12);

        WriteLine("{0} was a leap year: {1}", date1.Year, DateTime.IsLeapYear(date1.Year));
        WriteLine("{0} was a leap year: {1}", date2.Year, DateTime.IsLeapYear(date2.Year));
        WriteLine("=================================");
        return 8;
    }
}

This would produce:

1988 was a leap year: True
1990 was a leap year: False
=================================
Press any key to continue . . .

The Day of the Week

The DateTime structure is equipped with a property that can be used to retrieve the day of the week for a given date. The property is named DayOfWeek. To get the day of the week, access the DayOfWeek property a your DateTime value or variable. The values are stored in the DayOfWeek enumeration. Here is an example:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime date = new DateTime(1988, 10, 6);

        WriteLine("Date and Time:   {0}", date);
        WriteLine("Day of the week: {0}", date.DayOfWeek);
        WriteLine("======================================");
        return 10;
    }
}

This would produce:

Date and Time:   10/6/1988 12:00:00 AM
Day of the week: Thursday
======================================
Press any key to continue . . .

A Time Span

Common operations on dates include adding days to a date, subtracting months from a date, adding years, comparing dates to find out whether one occurs before another, etc. To perform some of these operations, a unit called an interval is considered as part of a date. A date interval is the number of days, months, or years that have elapsed, or would elapse, from one starting date to another ending date. Once you have specified this interval, you can then apply it to a date with the operation of your choice.

To support the ability to perform operations on dates, the .NET Framework provides a structure named TimeSpan. This structure is equipped with various members that would be applied on the TimeSpan structure. The value produced by this structure is then applied to a DateTime object. To create a date interval, declare a TimeSpan variable and initialize it with the desired value(s). To make this possible, the TimeSpan structure is equipped with various constructors.

Day-Based Operations

Adding Days to a Date Value

With the DateTime structure, you can add some days to an existing date. To support this, the DateTime structure is equipped with a method named AddDays. Its syntax is:

public DateTime AddDays(int days);

Here is an example of calling this method:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime startDate = new DateTime(1988, 10, 6);
        // This will be used to add 8 days to the previous date
        DateTime endDate = startDate.AddDays(8);

        WriteLine("Starting Date: {0}", startDate);
        WriteLine("Ending Date:   {0}", endDate);
        WriteLine("======================================");
        return 8;
    }
}

This would produce:

Starting Date: 10/6/1988 12:00:00 AM
Ending Date:   10/14/1988 12:00:00 AM
======================================
Press any key to continue . . .

If you pass a positive value to the DateTime.AddDays() method, a number of days is added to the DateTime variable.

Adding a Time Span Value

To allow you to add a date-based value to a date, the DateTime structure is equipped with a method named Add. Its syntax is:

public DateTime Add (TimeSpan value);

This method takes a TimeSpan argument and it returns a DateTime object. To use it, create a TimeSpan object that contains the value(s) to add. Here is an example:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime startDate = new DateTime(1988, 10, 6);
        // This will be used to add 172 days to the previous date
        TimeSpan ts = new TimeSpan(172, 0, 0, 0);
        // Pass the TimeSpan object to the date
        DateTime endDate = startDate.Add(ts);

        WriteLine("Starting Date: {0}", startDate);
        WriteLine("Ending Date:   {0}", endDate);
        WriteLine("======================================");
        return 10;
    }
}

This would produce:

Starting Date: 10/6/1988 12:00:00 AM
Ending Date:   3/27/1989 12:00:00 AM
======================================
Press any key to continue . . .

Subtracting Days from a Date Value

To let you subtract date values, the DateTime structure is equipped with an overloaded method named Subtract. The syntax of one of them takes a DateTime object:

public TimeSpan Subtract(DateTime value);

When calling this version, create and pass a DateTime object. This version produces a TimeSpan object. From that returned object, you can identify the value that was produced.

As an alternative to the DateTime.Subtract() method, you can call the DateTime.Add() method. If you want to subtract some days from a date, pass a negative value to the DateTime.AddDays() method. This method is able to figure out the year before, the month before, the day before, the day after, the month after, and the year after the designated date.

One of the constructors of the TimeSpan structure takes four arguments. Its syntax is:

public TimeSpan(int days, int hours, int minutes, int seconds);

The first argument of this constructor represents the number of days. If you are planning to add a number of days to a date, pass a positive integer as the first argument. If you want to subtract a date, pass a negative value. If you want to add only a number of days, pass only this argument.

Subtracting a Time Span Value

The other version of the DateTime.Subtract() method takes a TimeSpan object as argument:

public DateTime Subtract(TimeSpan value);

This time, pass a TimeSpan object to the method. As an alternative, the DateTime structure makes it possible to subtract a value from a date. To do this, pass a negative value to the DateTime.Add() method. This would produce a new DateTime object. Here is an example:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime startDate = new DateTime(1988, 10, 6);
        // This will be used to add 172 days to the previous date
        TimeSpan ts = new TimeSpan(-10, 0, 0, 0);
        // Pass the TimeSpan object to the date
        DateTime endDate = startDate.Add(ts);

        // And display it
        WriteLine("Starting Date: {0}", startDate);
        WriteLine("Ending Date:   {0}", endDate);
        WriteLine("======================================");
        return 11;
    }
}

This would produce:

Starting Date: 10/6/1988 12:00:00 AM
Ending Date:   9/26/1988 12:00:00 AM
======================================
Press any key to continue . . .

Month-Based Operations

Adding Months to a Date Value

To let you add a number of months to a date, the DateTime class is equipped with a method named AddMonths. Its syntax is:

public DateTime AddMonths(int months);

This method takes one argument as a number of months. If you pass the argument with a positive value, the months are added to the date.

Practical LearningPractical Learning: Introducing Operations on Date Values

Subtracting Months to a Date

To subtract a number of months from a date, you can call the DateTime.AddMonths() method. If you pass the argument with a negative value, the number of months is subtracted from the date.

Year-Based Operations

Adding or Subtracting Years to a Date

To get the date a few years before or after a known date, you can add years to, or subtract years from, a known date. To support this operation, the DateTime class provides a method named AddYears. Its syntax is:

public DateTime AddYears(int years);

The argument passed to the method is the number of years. A positive value (or a negative value) adds (or subtracts) the number of years to (or from) the date.

Logical Operations on Dates

Using the logical operators we reviewed for primitive types, you can compare the values of dates for equality, differences, lower or greater values. To support these operations, the DateTime structure has the logical operators configured appropriately.

To compare two dates, apply the desired Boolean operator the same way you would proceed for two variables of primitive types. Here is an example:

using System;



{
    
    {
        Title = "Dates Characteristics";

        DateTime startDate = new DateTime(1988, 10, 6);
        // This will be used to add 8 days to the previous date
        DateTime endDate = startDate.AddDays(8);

        WriteLine("Starting Date: {0}", startDate);
        WriteLine("Ending Date:   {0}", endDate);

        WriteLine("-----------------------------------------------------------");
        if (startDate < endDate)
            WriteLine($"{startDate} occurs before {endDate}");

        WriteLine("===========================================================");
        return 12;
    }
}

This would produce:

Starting Date: 10/6/1988 12:00:00 AM
Ending Date:   10/14/1988 12:00:00 AM
-----------------------------------------------------------
10/6/1988 12:00:00 AM occurs before 10/14/1988 12:00:00 AM
===========================================================
Press any key to continue . . .
  1. Start Microsoft Visual Studio and create a Windows Forms application named GasUtilityCompany3
  2. On the main menu, click Project -> Add New Item...
  3. In the left list, under Visual C# Items, click Code
  4. In the middle list, click Interface
  5. Change the file name to UtilityMeter
  6. Press Enter
  7. Change the document as follows:
    namespace GasUtilityCompany3
    {
        public interface IUtilityMeter
        {
            string MeterNumber { get; set; }
            string Make        { get; set; }
            string Model       { get; set; }
        }
    }
  8. In the Solution Explorer, right-click GasUtilityCompany3 -> Add -> Class...
  9. Change the file Name to GasMeter
  10. Click Add
  11. Change the document as follows:
    using System;
    
    namespace GasUtilityCompany31
    {
        public class GasMeter : IUtilityMeter
        {
            public string   MeterNumber  { get; set; }
            public string   Make         { get; set; }
            public string   Model        { get; set; }
            public int      CounterValue { get; set; }
        }
    }
  12. In the Solution Explorer, right-click GasUtilityCompany3 -> Add -> Class...
  13. Change the file name to Customer
  14. Click Add
  15. Change the class as follows:
    namespace GasUtilityCompany3
    {
        public class Customer
        {
            public string AccountNumber { get; set; }
            public string MeterNumber   { get; set; }
            public string FirstName     { get; set; }
            public string LastName      { get; set; }
            public string Address       { get; set; }
            public string City          { get; set; }
            public string County        { get; set; }
            public string State         { get; set; }
            public string ZIPCode       { get; set; }
        }
    }
  16. On the main menu, click Window -> Form1.cs [Design]
  17. Complete the design of the form as follows:

    Introducing the Calendar Control

    Control (Name) Text Other Properties
    Label   Customer Account Information

    BackColor: Gray
    ForeColor: White

    Label   Account #:  
    TextBox txtAccountNumber    
    Label   Customer Name:  
    TextBox txtCustomerName    
    Label   Address  
    TextBox txtAddress    
    TextBox txtCity    
    TextBox txtCounty    
    TextBox txtState    
    TextBox txtZIPCode    
    Label   Meter Information

    BackColor: Gray
    ForeColor: White

    Label   Meter Details:  
    TextBox txtMeterNumber    
    TextBox txtMeterDetails    
    Label   Meter Reading  
    Label   _________________________  
    Label   Counter Reading Start:  
    TextBox txtCounterReadingStart   TextAlign: Right
    Label   Counter Reading End:  
    TextBox txtCounterReadingEnd   TextAlign: Right
  18. On the form, click the Account # text box
  19. In the Properties window, click the Events button Events
  20. Double-click Leave
  21. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany32
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                /* This is the list of utility meters used by the company.
                 * Every device has a unique meter number. */
                meters = new GasMeter[]
                {
                    new GasMeter() { MeterNumber = "582741-38", Make = "Sinton International", Model = "D-244",    CounterValue =   138 },
                    new GasMeter() { MeterNumber = "293847-27", Make = "Archimeda",            Model = "LP2066",   CounterValue =  2866 },
                    new GasMeter() { MeterNumber = "928731-59", Make = "EnvioSmart",           Model = "84-D9703", CounterValue =  8016 },
                    new GasMeter() { MeterNumber = "520246-85", Make = "Garland Worldwide",    Model = "GFH-2260", CounterValue = 22683 },
                    new GasMeter() { MeterNumber = "797047-27", Make = "Archimeda",            Model = "LP2066",   CounterValue =   725 },
                    new GasMeter() { MeterNumber = "425837-14", Make = "EnvioSmart",           Model = "28-G4428", CounterValue =  6114 },
                    new GasMeter() { MeterNumber = "162460-82", Make = "Archimeda",            Model = "Di8000",   CounterValue = 15502 },
                    new GasMeter() { MeterNumber = "864085-92", Make = "Sinton International", Model = "D-244",    CounterValue =    83 }
                };
    
                /* This si the list of customers who use the gas produced and distributed by the company.
                 * Every customer uses a utility metter number. That number must (1) correspond to a gas 
                 * meter from the above list, (2) the gas meter a customer uses must be unique among the other customers. */
                customers = new Customer[]
                {
                    new Customer(){ AccountNumber = "620-9720-824", MeterNumber = "293847-27", FirstName = "Jefferey",    LastName = "Parriot", Address = "688 Gorman Str",     City = "Rockville",   County = "Montgomery",    State = "MD", ZIPCode = "20856" },
                    new Customer(){ AccountNumber = "4482-1397-851", MeterNumber = "425837-14", FirstName = "Christopher", LastName = "McGee",   Address = "3316 Sanderson Rd",  City = "Alexandria",  County = "",              State = "VA", ZIPCode = "22312" },
                    new Customer(){ AccountNumber = "852-9360-597", MeterNumber = "582741-38", FirstName = "Sandra",      LastName = "Rhodes",  Address = "11158 Grattos Ave",  City = "Hyattsville", County = "Prince George", State = "MD", ZIPCode = "20783" },
                    new Customer(){ AccountNumber = "209-5384-805", MeterNumber = "928731-59", FirstName = "Marco",       LastName = "Ramos",   Address = "9012 Jefferson Crt", City = "Washington",  County = "",              State = "DC", ZIPCode = "20012" },
                    new Customer(){ AccountNumber = "972-3848-393", MeterNumber = "797047-27", FirstName = "Gabrielle",   LastName = "Bayley",  Address = "799 Boomerang Str",  City = "Columbia",    County = "Howard",        State = "MD", ZIPCode = "21042" }
                };
    
                // Request/Get the customer's account number from the user 
                string acntNbr = txtAccountNumber.Text;
    
                // We will need to identify the gas meter that a customer is using.
                string striMeterNumber = string.Empty;
    
                // When the user has typed a customer's account number, visit each of the customers accounts.
                for (int i = 0; i <= customers.Length - 1; i++)
                {
                    // Find out if there is a customer record that has the accont number the user had entered.
                    if (customers[i].AccountNumber == acntNbr)
                    {
                        // If the user entered a valid customer's account, display the information of that customer
                        txtCustomerName.Text = string.Format("{0}, {1}", customers[i].LastName, customers[i].FirstName);
                        txtAddress.Text = customers[i].Address;
                        txtCity.Text = customers[i].City;
                        txtCounty.Text = customers[i].County;
                        txtState.Text = customers[i].State;
                        txtZIPCode.Text = customers[i].ZIPCode;
    
                        // Get the gas meter number the user is using
                        striMeterNumber = customers[i].MeterNumber;
    
                        // Since you found the customer record, stop looking
                        break;
                    }
                }
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        // Since you found the customer's gas meter, stop looking
                        break;
                    }
                }
            }
        }
    }
  22. To execute the application, on the main menu, click Debug -> Start Without Debugging:

    Introducing Operations on Date Values

  23. Click the Account # text box and type an account number, such as 620-9720-824

    Modeling a Window

  24. Press Tab:

    Modeling a Window

  25. Close the form and return to your programming environment
  26. On the main menu, click Window -> Form1.cs [Design]

Practical LearningPractical Learning: Introducing the Calendar Control

  1. On the Toolbox, under Common Controls, click MonthCalendar
  2. Click an unoccuped area of the form
  3. Once again, on the Toolbox, click MonthCalendar and click the form
  4. Complete the design of the form as follows:

    Introducing the Calendar Control

    Control (Name) Text
    Label   Reading Start Date
    Label   Reading End Date
    MonthCalendar mcReadingStartDate  
    MonthCalendar mcReadingEndDate  
  5. Click the GasMeter.cs tab and add a new property as follows:
    using System;
    
    namespace GasUtilityCompany32
    {
        class GasMeter :IUtilityMeter
        {
            public string   MeterNumber      { get; set; }
            public string   Make             { get; set; }
            public string   Model            { get; set; }
            public DateTime MeterReadingDate { get; set; }
            public int      CounterValue     { get; set; }
        }
    }

Practical LearningPractical Learning: Adding Days to a Date Value

  1. Change the document as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany32
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                . . .
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        mcReadingStartDate.SelectionStart = meters[i].MeterReadingDate;
    
                        mcReadingEndDate.SelectionStart = meters[i].MeterReadingDate.AddDays(30);
    
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        // Since you found the customer's gas meter, stop looking
                        break;
                    }
                }
            }
    
            private void txtCounterReadingEnd_Leave(object sender, EventArgs e)
            {
                . . .
    
                txtStateTaxes.Text = state.ToString("F");
                txtLocalTaxes.Text = local.ToString("F");
                txtAmountDue.Text = amtDue.ToString("F");
                txtCCFTotal.Text = consumption.ToString();
                txtTotalTherms.Text = totalTherms.ToString("F");
                txtOver50Therms.Text = over50Therms.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtFirst50Therms.Text = first50Therms.ToString("F");
                txtDeliveryTotal.Text = deliveryTotal.ToString("F");
                txtEnvironmentalCharges.Text = environment.ToString("F");
                txtDistributionAdjustment.Text = distribution.ToString("F");
                txtLatePaymentAmountDue.Text = (amtDue + 8.35).ToString("F");
                txtTransportationCharges.Text = transportationCharges.ToString("F");
                txtPaymentDueDate.Text = mcReadingEndDate.SelectionStart.AddDays(21).ToShortDateString();
            }
    
            private void mcReadingEndDate_DateChanged(object sender, DateRangeEventArgs e)
            {
    
            }
        }
    }
  2. To execute, press Ctrl + F5
  3. In the Account # text box, type 209-5384-805 and press Tab:

    Adding Days to a Date Value

  4. Click the Counter Reading End text box, type 8297 and presss Tab:

    Adding Days to a Date Value

  5. Close the form and return to your programming environment

Practical LearningPractical Learning: Subtracting a Date Value

  1. Implement the DateChanged event as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany32
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                . . .
            }
    
            private void txtCounterReadingEnd_Leave(object sender, EventArgs e)
            {
                . . .
            }
    
            private void mcReadingEndDate_DateChanged(object sender, DateRangeEventArgs e)
            {
                DateTime dtStart = mcReadingStartDate.SelectionStart;
                DateTime dtEnd = mcReadingEndDate.SelectionStart;
                TimeSpan tsDays = dtEnd.Subtract(dtStart);
    
                txtNumberOfDays.Text = tsDays.Days.ToString();
            }
        }
    }
  2. To execute the project, on the main menu, click Debug -> Start Without Debugging
  3. In the Account # text box, type 972-3848-393 and press Tab

    Subtracting a Date Value

  4. In the Reading End Date calendar, click 18

    Subtracting a Date Value

  5. Close the form and return to your programming environment

Practical LearningPractical Learning: Adding Months to a Date Value

  1. Change the code as follows:
    using System;
    using System.Windows.Forms;
    
    namespace GasUtilityCompany32
    {
        public partial class Form1 : Form
        {
            GasMeter[] meters = new GasMeter[7];
            Customer[] customers = new Customer[5];
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void txtAccountNumber_Leave(object sender, EventArgs e)
            {
                /* This is the list of utility meters used by the company.
                 * Every device has a unique meter number. */
                meters = new GasMeter[]
                {
                    new GasMeter() { MeterNumber = "582741-38", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021,  5, 10), CounterValue =   138 },
                    new GasMeter() { MeterNumber = "293847-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021,  8,  3), CounterValue =  2866 },
                    new GasMeter() { MeterNumber = "928731-59", Make = "EnvioSmart",           Model = "84-D9703", MeterReadingDate = new DateTime(2020, 12,  8), CounterValue =  8016 },
                    new GasMeter() { MeterNumber = "520246-85", Make = "Garland Worldwide",    Model = "GFH-2260", MeterReadingDate = new DateTime(2021,  5, 22), CounterValue = 22683 },
                    new GasMeter() { MeterNumber = "797047-27", Make = "Archimeda",            Model = "LP2066",   MeterReadingDate = new DateTime(2021, 10,  4), CounterValue =   725 },
                    new GasMeter() { MeterNumber = "425837-14", Make = "EnvioSmart",           Model = "28-G4428", MeterReadingDate = new DateTime(2021,  1,  1), CounterValue =  6114 },
                    new GasMeter() { MeterNumber = "162460-82", Make = "Archimeda",            Model = "Di8000",   MeterReadingDate = new DateTime(2020,  6,  3), CounterValue = 15502 },
                    new GasMeter() { MeterNumber = "864085-92", Make = "Sinton International", Model = "D-244",    MeterReadingDate = new DateTime(2021, 10,  5), CounterValue =    83 }
                };
    
                /* This si the list of customers who use the gas produced and distributed by the company.
                 * Every customer uses a utility metter number. That number must (1) correspond to a gas 
                 * meter from the above list, (2) the gas meter a customer uses must be unique among the other customers. */
                customers = new Customer[]
                {
                    new Customer(){ AccountNumber = "620-9720-824", MeterNumber = "293847-27", FirstName = "Jefferey",    LastName = "Parriot", Address = "688 Gorman Str",     City = "Rockville",   County = "Montgomery",    State = "MD", ZIPCode = "20856" },
                    new Customer(){ AccountNumber = "482-1397-851", MeterNumber = "425837-14", FirstName = "Christopher", LastName = "McGee",   Address = "3316 Sanderson Rd",  City = "Alexandria",  County = "",              State = "VA", ZIPCode = "22312" },
                    new Customer(){ AccountNumber = "852-9360-597", MeterNumber = "582741-38", FirstName = "Sandra",      LastName = "Rhodes",  Address = "11158 Grattos Ave",  City = "Hyattsville", County = "Prince George", State = "MD", ZIPCode = "20783" },
                    new Customer(){ AccountNumber = "209-5384-805", MeterNumber = "928731-59", FirstName = "Marco",       LastName = "Ramos",   Address = "9012 Jefferson Crt", City = "Washington",  County = "",              State = "DC", ZIPCode = "20012" },
                    new Customer(){ AccountNumber = "972-3848-393", MeterNumber = "797047-27", FirstName = "Gabrielle",   LastName = "Bayley",  Address = "799 Boomerang Str",  City = "Columbia",    County = "Howard",        State = "MD", ZIPCode = "21042" }
                };
    
                // Request the customer's account number from the user 
                string acntNbr = txtAccountNumber.Text;
    
                // We will need to identify the gas meter that a customer is using.
                string striMeterNumber = string.Empty;
    
                // When the user has typed a customer's account number, visit each of the customers accounts.
                for (int i = 0; i <= customers.Length - 1; i++)
                {
                    // Find out if there is a customer record that has the accont number the user had entered.
                    if (customers[i].AccountNumber == acntNbr)
                    {
                        // If the user entered a valid customer's account, display the information of that customer
                        txtCustomerName.Text = string.Format("{0}, {1}", customers[i].LastName, customers[i].FirstName);
                        txtAddress.Text = customers[i].Address;
                        txtCity.Text = customers[i].City;
                        txtCounty.Text = customers[i].County;
                        txtState.Text = customers[i].State;
                        txtZIPCode.Text = customers[i].ZIPCode;
    
                        mcReadingStartDate.SelectionStart = meters[i].MeterReadingDate;
    
                        // Get the gas meter number the user is using
                        striMeterNumber = customers[i].MeterNumber;
    
                        // Since you found the customer record, stop looking
                        break;
                    }
                }
    
                // Get a list of all the gas meters that the company is using and check each of them.
                for (int i = 0; i <= meters.Length - 1; i++)
                {
                    // If you find a gas meter that corresponds to the customer's account, ...
                    if (meters[i].MeterNumber == striMeterNumber)
                    {
                        // Display a summary of that gas meter
                        txtMeterNumber.Text = meters[i].MeterNumber;
                        txtMeterDetails.Text = string.Format("Meter: {0} {1}", meters[i].Make, meters[i].Model);
                        mcReadingStartDate.SelectionStart = meters[i].MeterReadingDate;
    
                        mcReadingEndDate.SelectionStart = meters[i].MeterReadingDate.AddDays(30);
    
                        txtCounterReadingStart.Text = meters[i].CounterValue.ToString();
    
                        // Since you found the customer's gas meter, stop looking
                        break;
                    }
                }
            }
    
            private void txtCounterReadingEnd_Leave(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtAccountNumber.Text))
                {
                    MessageBox.Show("You must enter the starting value of the counter reading.",
                                    "Quatro Gas Company");
                    return;
                }
    
                if (string.IsNullOrEmpty(txtMeterNumber.Text))
                {
                    MessageBox.Show("You must enter the meter number of the gas meter used by " +
                                    "the customer (normally, this is done by entering the customer's account number).",
                                    "Quatro Gas Company");
                    return;
                }
    
                if (string.IsNullOrEmpty(txtCounterReadingEnd.Text))
                {
                    MessageBox.Show("You must enter the ending value of the counter reading.",
                                    "Quatro Gas Company");
                    return;
                }
    
                int meterReadingStart = int.Parse(txtCounterReadingStart.Text);
                int meterReadingEnd = int.Parse(txtCounterReadingEnd.Text);
    
                int consumption = meterReadingEnd - meterReadingStart;
    
                double totalTherms = consumption * 1.0367;
                double first50Therms, over50Therms;
    
                if (totalTherms < 50)
                {
                    first50Therms = totalTherms * 0.5269;
                    over50Therms = 0;
                }
                else
                {
                    first50Therms = 50 * 0.5269;
                    over50Therms = (totalTherms - 50) * 0.4995;
                }
    
                /* We will use some random values for the transportation charge (my 
                 * research didn't make it clear to me how gas companies set this price. */
                Random   rndTransportation    = new Random();
                double[] transportationValues = { 9.75, 9.95, 10.25, 10.45, 10.85, 12.55, 13.50, 14.35 };
    
                double transportationCharges = transportationValues[rndTransportation.Next(1, transportationValues.Length)];
                double deliveryTotal = transportationCharges + first50Therms + over50Therms;
    
                double distribution = totalTherms * 0.11086;
                double environment = deliveryTotal * 0.0045;
                double state = transportationCharges * 0.0225;
                double local = transportationCharges * 0.05826;
                double totalCharges = transportationCharges + deliveryTotal + distribution + environment + local + state;
                double amtDue = totalCharges;
    
                txtStateTaxes.Text = state.ToString("F");
                txtLocalTaxes.Text = local.ToString("F");
                txtAmountDue.Text = amtDue.ToString("F");
                txtCCFTotal.Text = consumption.ToString();
                txtTotalTherms.Text = totalTherms.ToString("F");
                txtOver50Therms.Text = over50Therms.ToString("F");
                txtTotalCharges.Text = totalCharges.ToString("F");
                txtFirst50Therms.Text = first50Therms.ToString("F");
                txtDeliveryTotal.Text = deliveryTotal.ToString("F");
                txtEnvironmentalCharges.Text = environment.ToString("F");
                txtDistributionAdjustment.Text = distribution.ToString("F");
                txtLatePaymentAmountDue.Text = (amtDue + 8.35).ToString("F");
                txtTransportationCharges.Text = transportationCharges.ToString("F");
                txtPaymentDueDate.Text = mcReadingEndDate.SelectionStart.AddDays(21).ToShortDateString();
                txtLatePaymentDueDate.Text = mcReadingEndDate.SelectionStart.AddMonths(1).ToShortDateString();
            }
    
            private void mcReadingEndDate_DateChanged(object sender, DateRangeEventArgs e)
            {
                DateTime dtStart = mcReadingStartDate.SelectionStart;
                DateTime dtEnd = mcReadingEndDate.SelectionStart;
                TimeSpan tsDays = dtEnd.Subtract(dtStart);
    
                txtNumberOfDays.Text = tsDays.Days.ToString();
            }
        }
    }
  2. To execute, on the main menu, click Debug -> Start Without Debugging
  3. In the Account Number text box, type 972-3848-393 and press Tab
  4. In the Reading End Date calendar, click 8
  5. Click the Counter Reading End text box. Type 958 and press Tab:

    Adding Months to a Date Value

  6. Close the form and return to your programming environment

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2024, FunctionX Friday 10 June 2022 Next