Using TimeSpan and DateTime

TimeSpan is not even close to being the same as DateTime!

The DateTime structure and the TimeSpan structure appear to be very similar. From the Microsoft doc:

DateTime values are represented as the number of ticks (the number of 100-nanosecond intervals) that have elapsed since 12:00:00 midnight, January 1, 0001.

The value of a TimeSpan object is the number of ticks that equal the represented time interval. A tick is equal to 100 nanoseconds, or one ten-millionth of a second.

But they're not as compatible as you might think. In fact, programmers often have difficulty working with them together. A companion article to this one, Of Ticks and Timers, covers the use of the Tick event, the Ticks property, the Timer component, and the Timer class (Yes, all these are completely different things in VB.NET.) and the events, methods, and properties that can be used along with them.

This article is about TimeSpan and DateTime. Some similar confusion swirls around these two structures. The way to think about them is that DateTime is a point in time while TimeSpan is an interval. If you use a DateTime method that adds or subtracts two dates, you get a TimeSpan as a result. (But, beware, the familiar plus operator (+) concatenates two DateTime objects but it adds two TimeSpan objects.)

DateTime is handy because you can deal with it in an consistent way. DateTime is one of the "intrinsic" "Visual Basic data types" (see the Microsoft "Data Type Summary (Visual Basic)" in the language reference documentation.) You can express DateTime values using it's own "enclosing type" character, the pound sign (#).

For example, you can initialize and then change a DateTime using compatible syntax and values.

(By the way, another handy reference is the Microsoft page that describes the object icons and their meaning in Visual Studio: Class View and Object Browser Icons)

Dim theDateTime As DateTime = #12/7/1941 7:48:00 AM#
theDateTime = #12/8/1941 12:30:00 PM#

Date is completely equivalent.

Dim theDate As Date = #12/7/1941 7:48:00 AM#

And either the date or the time can be specified independently.

Dim theDate As Date = #12/7/1941#
Dim theTime As Date = #7:48:00 AM#

There are a raft of methods, properties and events that make this a very useful object.

TimeSpan isn't quite as well supported. Although both DateTime and TimeSpan are described in the Microsoft doc as "structures", it's not one of the intrinsic VB.NET fundamental data types and you have to use slightly more cumbersome syntax to both initialize and use it.

Dim theTimeSpan As New TimeSpan(7, 48, 0)

This initializes theTimeSpan to 7 hours, 48 minutes, and 0 seconds. Note that we had to use the New constructor keyword as well. But the same syntax does not work to change the value of a TimeSpan. (In fact, parentheses are wildly out of context.)

' Doesn't work
theTimeSpan = (12, 30, 0)

You can assign values to a TimeSpan with the Parse method. This is a Shared function, so you use it with the TimeSpan class directly. This statement assigns an interval equal to 12 hours and 30 minutes.

theTimeSpan = TimeSpan.Parse("0.12:30:00.00")

The Parse method has some flexibility. Both of these formats work as well.

theTimeSpan = TimeSpan.Parse("10")
theTimeSpan = TimeSpan.Parse("12:30:00.00")

The first yields an interval of 10 days and the second is 12 hours and 30 minutes.

DateTime also has a Parse method, with a handy cultural sensitivity. Ordinarily, you can Parse a string date like this:

theDateTime = Date.Parse("12/7/1941")
' Displays 12/7/1941 12:00:00 AM 

But if your dates are in the Japanese culture - year, month, day - then you can parse them that way too.

ci = New CultureInfo("ja-JP")
theDateTime = Date.Parse("1941/12/07", ci)
' ALSO Displays 12/7/1941 12:00:00 AM

There's another "date-time" structure called DateTimeOffset that solves a new problem. A DateTime object specifies a point in time, but it could be very different in a different time zone.

For example, December 7, 1941 was December 8, 1941 in Japan. The DateTimeOffset structure also includes an Offset property that defines the difference between the current DateTimeOffset instance's date and time and Coordinated Universal Time (UTC). This doesn't solve the whole problem ... there are still local differences like daylight savings time ... but it does give you a much more 'global' point in time reference.

Much of the "date-time" problem is really just differences in the way people like to see them. If your problem is displaying dates and times, you might want to try this article.

Formatting Strings, Numbers, and Other Objects