A recent post on c# corner provides a straightforward introduction to the TimeSpan object and shows a couple innocuous examples. Further down, Ms. Choksi disclaims any further nuances such as time zone differences or daylight saving.
The problem is her code is more harmful than helpful. The TimeSpan object is very tricky and everyone needs to take Daylight Saving Time into consideration. Ignoring the topic is setting folks up for trouble down the road.
Time Zones Are Irrelevant
Time zones are irrelevant because now is now wherever you are. It appears differently on your console screen because you may be in London or Sydney. But now is now everywhere simultaneously. If I were to serialize a timestamp, it would include my timezone offset. If I were to enter a timestamp now in Austin, and then you entered a timestamp in Sydney an hour later, guess what? The timespan is one hour. You can print it out the times in whatever timezone you want, but the DateTime objects themselves encapsulate timezone data.
DateTime dtSomeTime = DateTime.Now; dtSomeTime = dtSomeTime.ToUniversalTime();
The first line of code sets the instant in time on the object, encapsulating timezone and Daylight Saving Time information. The second line of code does not change the value of the object. No Effect. You can discard it.
Daylight Saving Time
What's wrong with this code?
// Oct 28 Noon DateTime dtDayOne = new DateTime(2006,10,28,12,0,0); // Oct 29 Noon DateTime dtDayTwo = new DateTime(2006,10,29,12,0,0); TimeSpan ts = dtDayTwo.Subtract(dtDayOne); Console.Write("Days Difference: " + ts.TotalDays); Console.Write("Hours Difference: " + ts.TotalHours); // Displays // > 1 // > 24
The problem is, well, the results displayed are wrong.
If you were providing a calculation for drive time for a long trip, you would be giving out the wrong answer. There are twenty-five hours between Noon Oct 28 and Noon Oct 29 (In US Central Standard Time). Daylight Saving Time. Fall Back and all that stuff. You can't ignore it. You can't disclaim it away. There's no hiding from it. You must deal with it.
So what is the right way to calculate time differences? The trick is to compare the time differences after each DateTime is converted to Universal Time. Like this:
// 2006 Oct 28 Noon DateTime dtDayOne = new DateTime(2006,10,28,12,0,0); // 2006 Oct 29 Noon DateTime dtDayTwo = new DateTime(2006,10,29,12,0,0); TimeSpan ts = dtDayTwo.ToUniversalTime().Subtract(dtDayOne.ToUniversalTime()); Console.Write("Days Difference: " + ts.TotalDays); Console.Write("Hours Difference: " + ts.TotalHours); // Displays // > 1.04166666666667 // > 25
This provides the correct result because Universal Time keeps marching forward two hours between 2am and 3am Central Time on October 29th.
DateTime Best Practices
There are other nuances of DateTime manipulation that every .NET programmer should be aware of and by far the best source of information is Dan Roger's Coding Best Practices Using DateTime in the .NET Framework.
The article is pretty lengthy, but it covers the full gamut of gotchas -- the stuff you get called out for at 4am on October 29th to fix. Dan's article is especially important if you are serializing DateTimes into XML.
Although it was written in 2004, the information is valid and applicable to every project done today. You could say it's....timeless.