5

I have the following code, which should return an offset of 60 (to show that in the UK at present, we are in British Summer Time - ie. 60 minutes ahead of GMT):

var info = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
DateTimeOffset localServerTime = DateTimeOffset.Now;
double off = localServerTime.Offset.TotalMinutes;
return off;

However, it returns 0.

Could anyone please help fix this for me?

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Mark
  • 7,778
  • 24
  • 89
  • 147
  • You didn't use `info` anywhere. So your `off` will be current time zone offset. – Soner Gönül Oct 22 '14 at 11:26
  • 1
    @vc74 The question is misleading. The `info` variable is initialised but otherwise unused. The returned offset is based only on `DateTimeOffset.Now`. –  Oct 22 '14 at 11:26
  • Interesting. That works fine for me (czech daylight savings time). Are you sure your server is setup correctly, with the proper time zone? – Luaan Oct 22 '14 at 11:28
  • @vc74 UTC == GMT, always. You seem to be saying that Britain is currently in GMT (or UTC) rather than BST, but I don't believe that's correct, and Wikipedia agrees with me that BST doesn't end until next weekend. –  Oct 22 '14 at 11:30
  • 1
    BST doesn't end until sunday and `DateTimeOffset.Now.Offset.TotalMinutes` returns 60 for me in the UK right now. – Ben Robinson Oct 22 '14 at 11:32
  • @hvd You're right, so the server must be configured in GMT in this case – vc 74 Oct 22 '14 at 11:39

4 Answers4

15

Use TimeZoneInfo.IsDaylightSavingTime Method (DateTimeOffset) to find if it is currently Daylight saving for your Timezone.

var info = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
DateTimeOffset localServerTime = DateTimeOffset.Now;
bool isDaylightSaving = info.IsDaylightSavingTime(localServerTime);

There are further examples here

Adrian Sanguineti
  • 2,455
  • 1
  • 27
  • 29
  • 7
    Using the timezone "Greenwich Standard Time" didn't work for me as it apparently doesn't support daylight savings. I had to use "GMT Standard Time" instead. – Zhorian Apr 20 '18 at 09:44
0

Your machine is not configured correctly if you get 0 and live in the UK. Probable causes are:

  • The machine's time zone is not set correctly. Click the clock on the taskbar to correct.
  • The machine is not configured to observe daylight savings. Click the clock.
  • The database that TimeZoneInfo consults for daylight savings rules in out of date or corrupted. It is stored in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones registry key.

Be careful about making radical changes, having it configured wrong might well have been done intentionally to work around some kind of flaw in a business-critical app that runs on the server. Talk to whomever administers the server first.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

To master conversion from one timezone to anther you need to see what's supported (how?) and what's not.

foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine("TimeZone Offset: {0} Name : {1}, Supports DLS: {2}", tz.BaseUtcOffset,tz.StandardName,tz.SupportsDaylightSavingTime);
}

This should give you the list all timezones including info about DayLightSaving. Notice that:

TimeZone Offset: 00:00:00 Name : Greenwich Standard Time, Supports DLS: False

TimeZone Offset: 00:00:00 Name : GMT Standard Time, Supports DLS: True

So you need to use "GMT Standard Time" because it supports daylight saving already. No work needs to be done.

Here is sample code:

private static string GetBSTTimeStamp(string timestamp)
{
    DateTime dt = DateTime.Parse(timestamp);
    //TimeZoneInfo bst = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
    //Console.WriteLine("Time zone supports dls? {0}", bst.SupportsDaylightSavingTime);
    //Console.WriteLine("Time zone offset? {0}", bst.BaseUtcOffset);
    DateTime dateTimeInUtc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(dt, "Eastern Standard Time", "GMT Standard Time");
    return dateTimeInUtc.ToString();
}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
0

Another option is to use Noda Time.

The following code works with Noda Time 1.4 and higher:

var zone = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default.ForId("Europe/London");
var zonedClock = NodaTime.SystemClock.Instance.InZone(zone);
var zonedDateTime = zonedClock.GetCurrentZonedDateTime();
bool isDST = zonedDateTime.IsDaylightSavingTime();
Console.WriteLine(isDST);
  • zone is a DateTimeZone object representing the UK's timezone, "Europe/London"
  • zonedClock is a ZonedClock object which represents, in this case, the system clock and the UK's timezone
  • zonedDateTime is a ZonedDateTime object representing the current date and time in the timezone ("the current instant provided by the underlying clock, adjusted to the time zone of this object")
  • isDST is a boolean indicating whether the current instant is in DST or not. At the time of writing (April 2018) this evaluates to true

With earlier versions of Noda where ZonedClock is not available, we can do this instead:

var zone = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default.ForId("Europe/London");
var now = Instant.FromDateTimeOffset(DateTimeOffset.Now);
var zonedDateTime = new ZonedDateTime(now, zone);
bool isDST = zonedDateTime.IsDaylightSavingTime();
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108