John Zabroski
John Zabroski

Reputation: 2357

Is there a C# static analysis tool for catching APIs that fail to meet functional requirements?

One of my biggest pet peeves is APIs that don't do what the average user would intuit the API would do.

Case-in-point: .NET's DateTime.ToUniversalTime. The documentation is frightening:

On Windows XP systems, the ToUniversalTime method recognizes only the current adjustment rule when converting from local time to UTC. As a result, conversions for periods before the current adjustment rule came into effect may not accurately reflect the difference between local time and UTC.

And later goes on to say:

On Windows XP systems, the ToUniversalTime method recognizes only the current adjustment rule for the local time zone, which it applies to all dates, including down-level dates (that is, dates that are earlier than the starting date of the current adjustment rule). Applications running on Windows XP that require historically accurate local date and time calculations must work around this behavior by using the FindSystemTimeZoneById method to retrieve a TimeZoneInfo object that corresponds to the local time zone and calling its TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) method.

This has to be the single most hilarious sentence of documentation ever created. Who doesn't require accurate local date and time calculations when using ToUniversalTime()? Why not just mark this method with ObsoleteAttribute?

At any rate, what I am looking for is a tool that I could mark assembly's with assembly-level metadata, such as [RequiresHistoricallyAccurateLocalDateAndTimeCalculationsAttribute]. Then if it finds any instances of ToUniversalTime(), flag them as compiler errors, in the same way that C# wouldn't let me access unmanaged code directly without unsafe annotations.

Upvotes: 2

Views: 200

Answers (2)

Tim M.
Tim M.

Reputation: 54387

This requirement seems more suited to code analysis rather than attribute decoration or compilation errors.

See: http://www.binarycoder.net/fxcop/html/index.html

This has to be the single most hilarious sentence of documentation ever created. Who doesn't require accurate local date and time calculations when using ToUniversalTime()? Why not just mark this method with ObsoleteAttribute?

Given the nature/complexity of date/time calculation, this isn't a particular frightening/shocking revelation.

If I was doing UTC processing on Windows XP or any other OS, I would first acquaint myself with the idiosyncrasies of the platform just as I would for pretty much any other complex operation. The alternative given (TimeZoneInfo) isn't bulletproof either as that is highly dependent on the platform.

With regards to the platform dependence of TimeZoneInfo...I'm referring to the OS.

When you start working with time zone conversion (from which many date-related issues originate), you use methods like FindSystemTimeZoneById. On the plus side, the method name makes it clear that you are working with the local system (so perhaps it's less ambiguous than ToUniversalTime()). However, the OS is queried for the list of time zones, so it's possible for the OS to return a bad list (I believe in Windows the values live in the registry), the list to be out of date (perhaps a badly patched machine), etc.

I noticed that Windows XP also seems to have ambiguity issues with TimeZoneInfo (see "Notes to Callers"):

On Windows XP systems (...) As a result, the method may not accurately report ambiguous time offsets for periods before the current adjustment rule came into effect. For more information, see the Notes for Callers section in the Local property.

And (as you pointed out), the underlying platform implementation might be flawed.

Furthermore, the time zones are referenced by string IDs. While these don't seem to change much, there is still the potential for "magic strings" stored in an application which no longer match a timezone.

At least that's what I've found, though my knowledge of the subject is far from exhaustive. My experience with .Net and universal time on Windows Server has been positive.

My point is that there is usually a good reason why the BCL (base class library) authors implemented things a certain way, even if it does lead to unexpected behavior. The alternative would be to omit the functionality altogether.

If you have identified this as a pitfall, then I think it's commendable that you are taking the time to mitigate it.

Upvotes: 3

Wiktor Zychla
Wiktor Zychla

Reputation: 48279

Make yourself friends with the FxCop tool. From what I understand, this is what you are looking for. It's a static analysis tool which can be extended with custom rules expressed as a C# code relying on the FxCop API.

Upvotes: 1

Related Questions