2
 var currentServerOffset = TimeZone.CurrentTimeZone.GetUtcOffset(new DateTime(1972, 03, 19, 02, 00, 00);

using the above returns the wrong offset, but when you pass through 26th March it is corrected.

it seems that this is off for a whole week, in my tests this has been in 1972 and 1973 ref: https://greenwichmeantime.com/info/calendars/bst-dates/

I am thinking it could be something to do with GetDaylightChanges being wrong in these years ref: https://learn.microsoft.com/en-us/dotnet/api/system.timezone.getdaylightchanges?view=netframework-4.8#remarks

as when i call this passing in 1972 or 1973 the start is off by 7 days.

How do i get around this?

  • What does `TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id).GetAdjustmentRules()` give you? In general, the Windows TZ database does not have historical data, only data enough to cover practical "current" times (and Windows wasn't around in 1972). On my (W10) system, the "Greenwich Standard Time" zone (which is presumably what you're using) has no dynamic adjustment rules, just the one covering the period since it was aligned with the rest of the EU. [Noda Time](https://nodatime.org/) reportedly does have the historic data (disclaimer: not personally tested). – Jeroen Mostert Jul 09 '19 at 14:43
  • Correct. Windows does not have historical data for all zones. It only guarantees completeness from 2010 forward, though there are a few zones that have older data. Also, the `TimeZone` class will *never* give you historical information, even for zones that have it. It always assumes the current set of transition rules. For that reason, `TimeZone` should be considered deprecated. Use `TimeZoneInfo` instead, or if you need historical data then use Noda Time as shown in howsec's answer. – Matt Johnson-Pint Jul 09 '19 at 22:34
  • Note that `TimeZoneInfo` on Linux or OSX (via .NET Core) *does* have historical information. – Matt Johnson-Pint Jul 09 '19 at 22:39
  • Thanks for all your replies, it is a shame I couldn't use the .net framework to resolve my issue, but I have installed NodaTime which for the test cases returns the correct offset. – David Milloy Strachan Jul 10 '19 at 06:47

1 Answers1

3

We couldn't get GetUtcOffset to work with historic dates. Instead we used Noda Time which should be as easy as:

var dt = Instant.FromUtc(1972, 03, 19, 02, 00, 00);
DateTimeZone zone = DateTimeZoneProviders.Tzdb["Europe/London"];
Offset offset = zone.GetUtcOffset(dt);
howsec
  • 46
  • 3
  • 1
    Good answer. If however, like the question, the *current* time zone is desired, then `DateTimeZoneProviders.Tzdb.GetSystemDefault()` can be used. – Matt Johnson-Pint Jul 09 '19 at 22:38