Looking for an absolute definition of "Local Time"
The expression "Local Time" is thrown around a lot in the MSDN documentation. When it is defined, this is the standard definition (example taken from the documentation for TimeZone.ToLocalTime) :
Local time is the date and time on the computer you are using
Is this absolutely always the case, with no ambiguity? In particular, since the Start and End properties of DaylightTime are defined as being in "local time," does this mean that a DaylightTime for Pacific should return different Start and End values in Denver than in Boston (requiring a time zone conversion be performed on the very structure that supports time zone conversions)?
Answers
Local time is the time on the computer that is running the application. Users almost always expect to see date/time values in their local time. However when you are dealing with distributed systems like databases and web servers then local time isn't reasonable. Think about your e-mail client for a second. Suppose you reside in DC and it is currently 11:00 AM your time. Now suppose another developer at your company located in CA sends you an e-mail. His time is 8AM but your time is 11AM. The e-mail client will show you that the e-mail was sent at 11AM but that is because it has translated the time from his PST to your EST (which is +3). However in his e-mail client he'll see the e-mail as being sent at 8AM.
If you need to share date/time values across machines (and especially across timezones) then you should always use UTC. UTC is guaranteed to be accurate around the world. That is how e-mail works. When the e-mail is generated the date/time that it is sent is converted from the user's local time to UTC. When your e-mail client receives an e-mail it translates the time from UTC back to your local time. If you were to go look at the raw message it would be in UTC. Databases almost always store date/time values in UTC. Most file formats also do the same thing.
My rule of thumb is to store everything in UTC and always translate to the user's local time only for UI displays. You can tell UTC formats normally because they end with Z when stored as a string or with a +-# value like (2005-12-10T12:35:40-4). If you are given just a date/time value then there is no way to know whether it is local or UTC.
As a final comment about local time note that there is ambiguity when you are dealing with daylight savings time because of the time changes. Unfortunately there isn't much you can do about it. .NET 2.0's DateTime has made working with UTC and the conversion between that and local time easier but ambiguities still exist.
In short, use UTC internally and translate to local time as needed. As a final note be aware that if you are creating a web app then local time has to be calculated on the client because local time on the web server may be different.
Michael Taylor - 12/30/05
All Replies
Local time is the time on the computer that is running the application. Users almost always expect to see date/time values in their local time. However when you are dealing with distributed systems like databases and web servers then local time isn't reasonable. Think about your e-mail client for a second. Suppose you reside in DC and it is currently 11:00 AM your time. Now suppose another developer at your company located in CA sends you an e-mail. His time is 8AM but your time is 11AM. The e-mail client will show you that the e-mail was sent at 11AM but that is because it has translated the time from his PST to your EST (which is +3). However in his e-mail client he'll see the e-mail as being sent at 8AM.
If you need to share date/time values across machines (and especially across timezones) then you should always use UTC. UTC is guaranteed to be accurate around the world. That is how e-mail works. When the e-mail is generated the date/time that it is sent is converted from the user's local time to UTC. When your e-mail client receives an e-mail it translates the time from UTC back to your local time. If you were to go look at the raw message it would be in UTC. Databases almost always store date/time values in UTC. Most file formats also do the same thing.
My rule of thumb is to store everything in UTC and always translate to the user's local time only for UI displays. You can tell UTC formats normally because they end with Z when stored as a string or with a +-# value like (2005-12-10T12:35:40-4). If you are given just a date/time value then there is no way to know whether it is local or UTC.
As a final comment about local time note that there is ambiguity when you are dealing with daylight savings time because of the time changes. Unfortunately there isn't much you can do about it. .NET 2.0's DateTime has made working with UTC and the conversion between that and local time easier but ambiguities still exist.
In short, use UTC internally and translate to local time as needed. As a final note be aware that if you are creating a web app then local time has to be calculated on the client because local time on the web server may be different.
Michael Taylor - 12/30/05
- Thank you for the detailed response, but my question was really far more targeted. As somene working on utility libraries, some of which deal with date-time issues, I need to be certain I am following the contract of the framework. Therefore, when MSDN says that the properties of the DaylightTime structure (see reference in MSDN) are in "local time," I need to be certain of that definition. If you are correct, and the two words 'local time' mean 'the machine of the computer using the application' in absolutely every place they appear in MSDN, then my function GetUnitedStatesEasternDaylightChanges MUST return these values in these cities:
Results of function GetUnitedStatesEasternDaylightChanges(2005) in various cities:
Boston : { 4/3/2005 02:00:00, 10/30/2005 02:00:00, 1 }
San Francisco: { 4/2/2005 11:00:00, 10/29/2005 11:00:00, 1}
Berlin: { 4/3/2005 09:00:00, 10/30/2005 07:00:00, 1} (Berlin starts DST a week earlier and, naturally, ends DST several hours earlier).
As you can clearly see, the library writer has to jump through some fat hoops if the DaylightTime structure really does have to be in the time zone of the computer running the application. It requires that I make DST-compliant conversions to create the structure that describes DST conversions... a chicken and egg problem that seems unnecessary and somewhat silly. I need someone to come here and tell me, "Silly or not, that is the requirement, and if your library is going to abide by the contract for the DaylightTime structure, those are the values that should be returned."
So... is that what you're telling me? Ahh, time zones. They are a different story because DateTime doesn't deal with time zones (at least not in 1.x). If you are wanting to get the date/time when DST starts or stops then you have to actually call the appropriate method on the timezone in question. I'm guessing that the returned value from GetDaylightTime will be in the local time of the time zone that it is called on. This sort of makes sense. The bigger issue is actually getting the time zone for the area you want.
Honestly I would skip this all together and look for a third-party solution. http://www.michaelbrumm.com/simpletimezone.html contains the time zone support classes that I use in my own libraries. It makes all this real easy to deal with. In the above case you can request the time zone you want and then call GetDaylightTime() to get the DST and then use the other methods on the SimpleTimeZone class to convert to UTC or do whatever you want with the results. With the above library it will return the value in the local time of the associated time zone. Thus if you call GetDaylightTime() for a specific time zone it'll return the same value irrelevant of what time zone you are currently in.
The .NET framework doesn't even support dealing with time zones other than the current time zone so it is understandable that they don't really clarify or support interaction between time zones.
Hope this helps,
Michael Taylor - 12/30/05
TaylorMichaelL wrote: I'm guessing that the returned value from GetDaylightTime will be in the local time of the time zone that it is called on.
So I guess you see where I'm coming from, and that 'local time' may not, in fact, always mean machine local time... hence the maddening ambiguity.
TaylorMichaelL wrote: Honestly I would skip this all together and look for a third-party solution. http://www.michaelbrumm.com/simpletimezone.html contains the time zone support classes that I use in my own libraries.
Actually, I've examined SimpleTimeZone and it does the job, but only if you make a million assumptions about what 'local time' means in different places. In particular, MSDN's base class definition for ToLocalTime() states that the return value must be in machine local time, and SimpleTimeZone fails to do this.
However, if 'local time' does always mean machine local time, then it is actually impossible to convert an item in a foreign time zone to your current time zone using the base class interfaces of the .NET framework... try it. Therefore, either 'local time' is an ambiguously defined term or the date-time framework has issues.
TaylorMichaelL wrote: The .NET framework doesn't even support dealing with time zones other than the current time zone so it is understandable that they don't really clarify or support interaction between time zones.
I think you're taking it too easy on the framework. What is the purpose of any of these classes if not to support multiple time zones? Why is System.TimeZone abstract if it is not meant as a base class for other time zones? Regardless, the documentation for a framework library should not use ambiguous terminology.
I wish someone from Microsoft would drop in and answer these questions, because the lack of answers is making my job very difficult.
The documentation for GetDaylightChanges doesn't mention anything about local time so there is no ambiguity. It simply states that it returns the date/time when DST occurs. Whether it is UTC or not is undocumented. It does however mention that if the "current time zone" doesn't use DST then ... which is incorrect because it uses the time zone that it is called upon and not the current time zone however as I mentioned .NET only supports a single time zone right now so it is technically accurate.
I disagree with the SimpleTimeZone comments. I have used SimpleTimeZone on web apps that were used across the US and, provided I store everything in UTC internally and use the appropriate conversion for the UI it always works for me. Other than the 1 or 2 times when ambiguity can occur when translating from a TZ back to UTC it has never failed me. Perhaps you can provide an example of where it doesn't work properly so I can see the problem you are having.
I concur that the existing .NET classes are insufficient for multiple time zones but honestly how many apps really need to display date/times in formats other than time zones except to demonstrate something or as a sample app? I can't think of any. Even web servers can't do that because the web browser doesn't really provide enough reliable info to determine the TZ anyway. In the few cases where it might be nice however I find that SimpleTimeZone to be suitable. Note however that I personally took the library and modified it to make it easier to use for my needs because I felt it followed to closely to the existing .NET code and therefore was harder to use.
Finally, to be fair to MS time zones, DST and all that are actually political issues more than anything. A time zone is determined by politics and not some governing body. Even DST is not standard (even in the US). Therefore the ideal solution of providing some static time zone instances for each of the supported time zones is just prone for failure. MS has taken steps to better globalize .NET in 2.0 and hopefully multiple time zones are on their list of things to add in a future release.
Nice chatting with you. Good luck in your endevour.
Michael Taylor - 12/30/05
TaylorMichaelL wrote: The documentation for GetDaylightChanges doesn't mention anything about local time so there is no ambiguity. It simply states that it returns the date/time when DST occurs. Whether it is UTC or not is undocumented.
Check the constructor, Start property, and End property.
TaylorMichaelL wrote: I disagree with the SimpleTimeZone comments. I have used SimpleTimeZone on web apps that were used across the US and, provided I store everything in UTC internally and use the appropriate conversion for the UI it always works for me. Other than the 1 or 2 times when ambiguity can occur when translating from a TZ back to UTC it has never failed me. Perhaps you can provide an example of where it doesn't work properly so I can see the problem you are having.
I have no doubt it functions correctly according to its own contract. However, since it uses System.TimeZone as a base class, it must honor the System.TimeZone contract as well. Since System.TimeZone.ToLocalTime()'s base class contract states that it returns a time in the time zone of the machine being used, any result from SimpleTimeZone.ToLocalTime that is actually useful (i.e. in the target time zone) is incorrect.
This is not just me being pedantic. This is basic OOP. Any child of a base class must expect to be used as that base class and must honor its contract. The problem here is that some of the Microsoft.NET date-time contracts are clearer than others... and at least one of the clear ones (ToLocalTime again) just doesn't make sense. I could go ahead and write my libraries with my own assumptions about these contracts, but I would be putting myself at risk of being wrong and seeing my code broken by future versions. Several classes derived from System.TimeZone were in fact broken by Microsoft.NET 2.0 by taking this risk (http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=fb328fdb-c488-45e4-a08d-481cc0e3a436)
TaylorMichaelL wrote: I concur that the existing .NET classes are insufficient for multiple time zones but honestly how many apps really need to display date/times in formats other than time zones except to demonstrate something or as a sample app? I can't think of any.
Scheduling, particularly enterprise scheduling where meetings must be organized across disparate time zones and even countries.
But this is getting well outside the parameters of the discussion. Rest assured that I am not engaging in some academic exercise here. I'm just looking for guidance and clarification regarding Microsoft's intentions for these many date-time classes that would be useful for cross-time zone calculations if the documentation weren't so insistent that they're not.
-- Russ

