Working with Dates and Times - Variables and Calculations - C# 24-Hour Trainer (2015)

C# 24-Hour Trainer (2015)

Section II

Variables and Calculations

Lesson 15

Working with Dates and Times

One of C#'s more confusing data types is DateTime. A DateTime represents a date, a time, or both. For example, a DateTime variable might represent Thursday April 1, 2020 at 9:15 AM.

In this lesson, you learn how to work with dates and times. You learn how to create DateTime variables, find the current date and time, and calculate elapsed time.

Creating DateTime Variables

C# doesn't have DateTime literal values so you can't simply set a DateTime variable equal to a value as you can with some other data types. Instead you can use the new keyword to initialize a new DateTime variable, supplying arguments to define the date and time.

For example, the following code creates a DateTime variable named aprilFools and initializes it to the date April 1, 2020. It then displays the date using the short date format described in Lesson 14 and by calling the variable's ToShortDateString method:

DateTime aprilFools = new DateTime(2020, 4, 1);

MessageBox.Show(aprilFools.ToString("d"));

MessageBox.Show(aprilFools.ToShortDateString());

The preceding code uses a year, month, and day to initialize its DateTime variable, but the DateTime type lets you use many different kinds of values. The three most useful combinations of arguments specify (all as integers):

· Year, month, day

· Year, month, day, hour, minute, second

· Year, month, day, hour, minute, second, milliseconds

You can also add a kind parameter to the end of the second and third of these combinations to indicate whether the value represents local time or UTC time. (Local and UTC times are explained in the next section.) For example, the following code creates a DateTimerepresenting 12 noon on March 15, 2020 in the local time zone:

DateTime idesOfMarch =

new DateTime(2020, 3, 15, 12, 0, 0, DateTimeKind.Local);

Local and UTC Time

Windows has several different notions of dates and times. Two of the most important of these are local time and Coordinated Universal Time (UTC).

Local time is the time on your computer as it is configured for a particular locale. It's what you and a program's user typically think of as time.

UTC time is basically the same as Greenwich Mean Time (GMT), the time at the Royal Academy in Greenwich, London.

For most everyday tasks, local time is fine. If you need to compare data on computers running in different time zones, however, UTC time can make coordination easier. For example, if you want to know whether a customer in New York created an order before another customer created an order in San Salvador, UTC lets you compare the times without worrying about the customers' time zones.

A DateTime object has a Kind property that indicates whether the object represents local time, UTC time, or an unspecified time. When you create a DateTime, you can indicate whether you are creating a local or UTC time. If you do not specify the kind of time, C# assumes you are making an unspecified time.

After you create a DateTime, its ToLocalTime and ToUniversalTime methods convert between local and UTC times.

NOTE

The ToLocalTime and ToUniversalTime methods don't affect a DateTime if it is already in the desired format. For example, if you call ToLocalTime on a variable that already uses local time, the result is the same as the original variable.

DateTime Properties and Methods

The DateTime type provides many useful properties and methods for manipulating dates and times. Table 15.1 summarizes some of DateTime's most useful methods. Static methods are indicated with an asterisk. You invoke static methods by using the type name rather than a variable name, as in DateTime.IsLeapYear(2020).

Table 15.1

Method

Purpose

Add

Adds a TimeSpan to the DateTime. The following section describes TimeSpan.

AddDays

Adds a specified number of days to the DateTime.

AddHours

Adds a specified number of hours to the DateTime.

AddMinutes

Adds a specified number of minutes to the DateTime.

AddMonths

Adds a specified number of months to the DateTime.

AddSeconds

Adds a specified number of seconds to the DateTime.

AddYears

Adds a specified number of years to the DateTime.

IsDaylightSavingsTime

Returns true if the date and time is within the Daylight Savings Time period for the local time zone.

IsLeapYear*

Returns true if the indicated year is a leap year.

Parse*

Parses a string and returns the corresponding DateTime.

Subtract

Subtracts another DateTime from this one and returns a TimeSpan. The following section says more about TimeSpan.

ToLocalTime

Converts the DateTime to a local value.

ToLongDateString

Returns the DateTime in long date format.

ToLongTimeString

Returns the DateTime in long time format.

ToShortDateString

Returns the DateTime in short date format.

ToShortTimeString

Returns the DateTime in short time format.

ToString

Returns the DateTime in general format.

ToUniversalTime

Converts the DateTime to a UTC value.

Table 15.2 summarizes the DateTime's most useful properties.

Table 15.2

Property

Purpose

Date

Gets the DateTime's date without the time.

Day

Gets the DateTime's day of the month between 1 and 31.

DayOfWeek

Gets the DateTime's day of the week, as in Monday.

DayOfYear

Gets the DateTime's day of the year between 1 and 366. (Leap years have 366 days.)

Hour

Gets the DateTime's hour between 0 and 23.

Kind

Returns the DateTime's kind: Local, Utc, or Unspecified.

Millisecond

Gets the DateTime's time's millisecond.

Minute

Gets the DateTime's minute between 0 and 59.

Month

Gets the DateTime's month between 1 and 12.

Now*

Gets the current date and time.

Second

Gets the DateTime's second between 0 and 59.

TimeOfDay

Gets the DateTime's time without the date.

Today*

Gets the current date without a time.

UtcNow*

Gets the current UTC date and time.

Year

Gets the DateTime's year.

TimeSpans

A DateTime represents a point in time (July 20, 1969 at 20:17:40). A TimeSpan represents an elapsed period of time (1 day, 17 hours, 27 minutes, and 12 seconds).

One of the more useful ways to make a TimeSpan is to subtract one DateTime from another to find the amount of time between them. For example, the following code calculates the time that elapsed between the first and last manned moon landings:

DateTime firstLanding = new DateTime(1969, 7, 20, 20, 17, 40);

DateTime lastLanding = new DateTime(1972, 12, 11, 19, 54, 57);

TimeSpan elapsed = lastLanding - firstLanding;

Console.WriteLine(elapsed.ToString());

The code creates DateTime values to represent the times of the two landings. It then subtracts the last date from the first to get the elapsed time and uses the resulting TimeSpan's ToString method to display the duration. The following text shows the result in the formatdays.hours:minutes:seconds:

1239.23:37:17

Table 15.3 summarizes the TimeSpan's most useful properties and methods.

Table 15.3

Property

Meaning

Days

The number of days.

Hours

The number of hours.

Milliseconds

The number of milliseconds.

Minutes

The number of minutes.

Seconds

The number of seconds.

ToString

Converts the TimeSpan into a string in the format days.hours:minutes:seconds.fractionalSeconds.

TotalDays

The entire TimeSpan represented as days. For a 36-hour duration, this would be 1.5.

TotalHours

The entire TimeSpan represented as hours. For a 45-minute duration, this would be 0.75.

TotalMilliseconds

The entire TimeSpan represented as milliseconds. For a 1-second duration, this would be 1,000.

TotalMinutes

The entire TimeSpan represented as minutes. For a 1-hour duration, this would be 60.

TotalSeconds

The entire TimeSpan represented as seconds. For a 1-minute TimeSpan, this would be 60.

Note that you can use the + and – operators to add and subtract TimeSpans, getting a new TimeSpan as a result. This works in a fairly obvious way. For example, a 90-minute TimeSpan minus a 30-minute TimeSpan gives a 60-minute TimeSpan.

Try It

In this Try It, you use DateTime and TimeSpan variables to build the stopwatch application shown in Figure 15.1. When the user clicks the Start Button, the program starts its counter. When the user clicks the Stop Button, the program stops the counter.

Screenshot of Stopwatch window displaying a sample time of 03:14:15.92 with the Start button highlighted on the upper left corner and the Stop button on the upper right corner.

Figure 15.1

Normally the TimeSpan's ToString method displays a value in the format d.hh:mm:ss.fffffff. In this example, you use string.Format to display the elapsed time in the format hh:mm:ss.ff.

Lesson Requirements

In this lesson, you:

· Create the form shown in Figure 15.1. In addition to the controls that are visible, give the form a Timer with Interval = 10. Initially disable the Stop button.

· When the user clicks the Start button, start the Timer, disable the Start button, and enable the Stop button.

· When the user clicks the Stop button, stop the Timer, enable the Start button, and disable the Stop button.

· When the Timer's Tick event fires, display the elapsed time in the format hh:mm:ss.ff.

NOTE

You can download the code and resources for this lesson from the website at www.wrox.com/go/csharp24hourtrainer2e.

Hints

· TimeSpan doesn't use the same formatting characters as a DateTime, so, for example, you can't simply use a format string such as hh:mm:ss.ff. Instead use the TimeSpan properties to get the elapsed hours, minutes, seconds, and milliseconds and then format those values.

Step-by-Step

· Create the form shown in Figure 15.1. In addition to the controls that are visible, give the form a Timer with Interval = 10. Initially disable the Stop button.

1. Add the Start and Stop buttons and a Label to the form as shown in Figure 15.1. Set the Stop button's Enabled property to False.

2. Add a Timer and set its Interval property to 10 milliseconds.

· When the user clicks the Start button, start the Timer, disable the Start button, and enable the Stop button.

1. To remember the time when the user clicked the Start button, create a DateTime field named StartTime:

2. // The time when the user clicked Start.

private DateTime StartTime;

3. Add the following code to the Start button's Click event handler:

4. // Start the Timer.

5. private void startButton_Click(object sender, EventArgs e)

6. {

7. StartTime = DateTime.Now;

8. startButton.Enabled = false;

9. stopButton.Enabled = true;

10. updateLabelTimer.Enabled = true;

}

· When the user clicks the Stop button, stop the Timer, enable the Start button, and disable the Stop button.

1. Add the following code to the Stop button's Click event handler:

2. // Stop the Timer.

3. private void stopButton_Click(object sender, EventArgs e)

4. {

5. startButton.Enabled = true;

6. stopButton.Enabled = false;

7. updateLabelTimer.Enabled = false;

}

· When the Timer's Tick event fires, display the elapsed time in the format hh:mm:ss.ff.

1. Use code similar to the following. Notice that the code divides the number of milliseconds by 10 to convert it into hundredths of seconds:

2. // Display the elapsed time.

3. private void updateLabelTimer_Tick(object sender, EventArgs e)

4. {

5. // Subtract the start time from the current time

6. // to get elapsed time.

7. TimeSpan elapsed = DateTime.Now - StartTime;

8. // Display the result.

9. elapsedTimeLabel.Text = string.Format(

10. "{0:00}:{1:00}:{2:00}.{3:00}",

11. elapsed.Hours,

12. elapsed.Minutes,

13. elapsed.Seconds,

14. elapsed.Milliseconds / 10);

}

Exercises

1. The System.Diagnostics.Stopwatch class acts like a stopwatch. It provides methods to start, reset, and stop timing. Copy the program you built for the Try It and modify it so it uses the Stopwatch class instead of a DateTime. Hints:

· Use the Stopwatch's Elapsed property to see how long it's been since the watch was started.

· Make the Start button call the watch's Start method.

· Make the Stop button call the watch's Reset method to stop timing and reset the watch's elapsed time to 0.

2. [Hard] Copy the program you built for Exercise 1 and add a Reset button. The Start button should start the stopwatch, the Stop button should pause it, and the Reset button should reset the stopwatch to 0. Because the purpose of the Stop button has changed, you should change its text to Pause. Change the name of the button and its event handler to match. Only enable the Reset button when the stopwatch is stopped and has non-zero elapsed time. (There's no need to reset it if the elapsed time is already 0.)

3. Make a program with a Birth Date TextBox and a Calculate Button. When the user enters a birth date and clicks the Button, calculate the person's current age and add items to a ListBox that display the age converted into each of days, hours, minutes, and seconds. Format all of the values with thousands separators and two digits after the decimal place.

4. Copy the program you wrote for Exercise 3 and modify it to also display the user's age in years and months. Hint: The DateTime class doesn't have TotalYears or TotalMonths properties (probably because Microsoft didn't want to figure out how to handle leap years). Calculate the number of years by dividing the number of days by 365.2425. Calculate the number of months by multiplying the number of years by 12.

5. Make a program that lets the user enter a birth date, heart rate, and respiration rate. When the user clicks the Calculate button, display the number of heartbeats and breaths since birth. (Typical adult rates range from 12 to 20 breaths per minute and 60 to 100 heartbeats per minute.) Display the results in millions as in “988 million.”

6. Make a program that lets you enter a birth date and then displays the date including the weekday for that date and the next nine birthdays.

7. Make a program with two TextBoxes for dates and a Button. When the user clicks the Button, the program should display the time between the dates.

8. Modify the program you built for Exercise 7 to use DateTimePicker controls instead of TextBoxes. To keep things simple, just display the total number of days between the dates using the N0 format specifier. Use the controls' Value properties to get the selected dates. (This control prevents users from entering invalid dates such as April 45.)

9. Write a program that takes the user's birth date as an input and displays the user's age in years on the different planets in our solar system. Hint: The orbital periods for the planets in Earth years are Mercury = 0.24, Venus = 0.62, Earth = 1.00, Mars = 1.88, Jupiter = 11.86, Saturn = 29.46, Uranus = 84.01, Neptune = 164.8, and (if you want to consider Pluto a planet) Pluto = 247.7.

10.Make a countdown timer. When the program starts, it should display a custom dialog where the user can enter a date and time. Then the main program should display the number of days, hours, minutes, and seconds until that time, updated every second.

NOTE

Please select the videos for Lesson 15 online at www.wrox.com/go/csharp24hourtrainer2evideos.