It seems System.TimeZoneInfo.GetSystemTimeZones sometimes returns UTC with a StandardName of "Coordinated Universal Time", and sometimes as "Co-ordinated Universal Time".
Infragistics.Win.TimeZoneInfo.FromStandardName appears to return a timezone from the latter, but not the former.
Why doesn't Infragistics.WIn.TimeZoneInfo allow a lookup on the Id? Surely this would be more reliable than having to do so by name?
Hello Campbell,
Thank you for contacting Infragistics. The issue at hand is unclear, please clarify. Is this issue machine dependent? Are you able to isolate this on multiple different machines? If so please provide a sample application demonstrating the issue.
Take these two excerpts from the Registry of two different machines, from
As you can (hopefully) see, the Std key (StandardName) on both of these timezones differ, by the dash.
If am am trying to obtain the Infragistics.Win.TimeZoneInfo from the System.TimeZoneInfo, the only way I can see to do this is using the FromStandardName function, i.e.
foreach (System.TimeZoneInfo tziSystem in System.TimeZoneInfo.GetSystemTimeZones()) { if (tziSystem.Id == "UTC") { Infragistics.Win.TimeZoneInfo tziInfragistics = Infragistics.Win.TimeZoneInfo.FromStandardName(tziSystem.StandardName); Debug.Assert(tziInfragistics != null, "Unable to look up TimeZone"); } }
So I did some testing on my machine and I ran this code: var timeZones = System.TimeZoneInfo.GetSystemTimeZones();And I looked at the list, and on my machine, I have "Coordinated Universal Time" on the list without the dash.
So then I looped through all the timeZones in the list and called Infragistics.Win.TimeZoneInfo.FromStandardName passing in the StandardName of each one. And I get an Infragistics.Win.TimeZoneInfo object every time. They match up fine.
So you seem to be saying that passing in the name without the dash does NOT work for you on your machine. But that's the opposite of what I am seeing on my machine - at least in the case without the dash. I don't have another machine to test, but I went into the registry and found the key for UTC and changed the "Std" value from "Coordinated Universal Time" to "Co-ordinated Universal Time" and tried again, and that also works fine. So that seems to prove that both the DotNet Framework and our list of TimeZoneInfos are both coming from the registry on the machine.Just to be sure, I stepped into our FromStandardName method and I can see that when we build the list, we are building the list of TimeZoneInfos by the StandardName and we are pulling those names from the registry. So on any given machine, the StandardNames of our TimeZoneInfos will always match up. I can also see that our code has a fallback mechanism so that if we are unable to access the registry for whatever reason, we keep a hard-coded list of the TimeZoneInfo data. But neither "Coordinated Universal Time" nor "Co-ordinated Universal Time" is on the backup list as far as I can see. So if your call to FromStandardName is failing, it can only be for one of two reasons:
1) The application failed to access the system registry and was forced to fall back to the hard-coded list. In which case, neither "Coordinated Universal Time" nor "Co-ordinated Universal Time" would work, since neither is on our backup list. 2) You are not getting both lists from the same machine. Like maybe you have a cached list or you are storing the StandardName of the TimeZone on one machine and trying to call FromStandardName on some other machine where it doesn't exist.
Thanks for your in-depth analysis. I've done some more digging, and it looks like it might be an issue with the System TimeZoneInfo.FindSystemTimeZoneById.
What we're doing, is storing the System TImeZone Id in a database, which in this case is "UTC". To then get back to the Infragistics timezone, we're first getting the system timezone with System.TimeZoneInfo.FindSystemTimeZoneById("UTC"), and then using the StandardName from that timezone to look up the Infragistics equivalent.
But it seems that on some machines, the System TimeZone returned isn't what I would expect. Here's an example:
(Sorry, the hidden line is:if (tzi != null) tziInfragistics = Infragistics.Win.TimeZoneInfo.FromStandardName(tzi.StandardName);)
As you can see, when we try to get the timezone back from the ID, it returns a different object to what we'd expect, and we're then trying to look the Infragistics zone up by the name "UTC".
This doesn't happen on all machines - I tested it on another and it successfully returned the correct System TImezone, and from there, the Infragistics one is looked up successfully.
Aside from explicitly working around this case, I can't think of a decent solution to this. Storing the Id seems the sensible thing to do, given this should be consistent across machines.
I'm straining my brain to wrap my head around what's going on here. And I can't honestly claim to be an expert on TimeZone or StandardNames or Ids. But it seems like you are making a the assumption here that the Id on one machine will always match up to the same StandardName on another machine, and that's not the case. But that's just the way MS is setting up the registry, and I'm not sure what we could do about that...Except to give you some facility to get a TimeZoneInfo from the Id, instead of a StandardName, which I think is what you were asking for in your original post. Is that right?
Ah ok, that makes sense. I think I'm okay for the time being, but will get back in touch if it becomes a problem later on. Thanks again for your help.
So it looks like what probably happened here is that there were no Ids when we created the TimeZoneInfo class. And the Id was added by Microsoft later on (in CLR3.5). So that's why we never had them.Working around the issue by checking for both strings is still your best and fastest way to get your application going. But if you think it would be important to have this in some future release, we could probably add it in pretty easily.
Thanks Mike.
I think working around it and just checking for both strings is probably your best bet right now. That's certainly the fastest way for you to get going. I sent an inqury to the guys who wrote this code to see if anyone remembers why we are using StandardName instead of Id. There's probably a good reason, but I don't know what it is, myself. I tried using reflection to get the entire list of TimeZoneInfo objects so you could loop through the manually and find the one with the matching Id, just as another potential workaround. But that doesn't work because Infragistics.Win.TimeZoneInfo doesn't even store the Id. So there's no way to match up to an Id even if you could get the entire list.
Hi Mike.
I'm making the assumption that timezone Ids are consistent across different machines, not StandardNames. It seems the latter is not the case, which is why it seems somewhat odd that Infragisics implement a FromStandardName function, rather than a FromId function on the TimeZoneInfo class. I think doing so would remove any ambiguity and prevent null being returned.
Thanks Michael, I think the workaround I have just now is sufficient, but there may be other examples aside from UTC where this occurs, in which case it could crop up again.
Campbell