I've seen that many websites (usually forums) allow users to specify their TimeZone preferences by selecting:
- the TimeZone
- whether or not to use DST
As far as I know, when doing conversions, .NET always takes DST into account, so the question is:
How can the "do not use DST" part be implemented in C#?
Below this point I present what I managed to do so far, but it feels hacky and I was wondering if there was a cleaner/better approach.
First, to make sure that DST is applied automatically, I wrote the following test:
[Test]
public void DateTimeConversion_ToLocalTime_HandlesDSTByDefault()
{
    var utcDateInDstInterval = new DateTime(2012, 07, 15, 0, 0, 0, DateTimeKind.Utc);
    var utcDateOutisdeDstInterval = new DateTime(2012, 02, 15, 0, 0, 0, DateTimeKind.Utc);
    var roTimezone = TimeZoneInfo.FindSystemTimeZoneById("GTB Standard Time");
    Assert.AreEqual(3, TimeZoneInfo.ConvertTimeFromUtc(utcDateInDstInterval, roTimezone).Hour);
    Assert.AreEqual(2, TimeZoneInfo.ConvertTimeFromUtc(utcDateOutisdeDstInterval, roTimezone).Hour);
}
This test passes, showing that:
- when no DST applies (for example in winter) the Romanian time is UTC + 2 hours
- when DST applies (for example in summer) the Romanian time is UTC + 3 hours
- when doing DateTime conversions, DST is automatically taken into account
Next, I noticed the TimeZoneInfo.GetAdjustmentRules() method that returns an array of AdjustmentRule objects and figured out that if I undo the effects of these rules I could get the DST-unaffected value.
So I wrote the following method that does this if the DateTime object is affected by DST:
private DateTime RemoveDSTFromDateTime(DateTime dateTime, TimeZoneInfo timeZoneInfo)
{
    if (!dateTime.IsDaylightSavingTime())
        return dateTime;
    var result = dateTime;
    foreach (var adjustmentRule in timeZoneInfo.GetAdjustmentRules())
        result = result.Subtract(adjustmentRule.DaylightDelta);
    return result;
}
Back to the original DST/No DST scenario, but this time forcing the result to be unaffected by DST:
[Test]
public void DateTimeConversion_ToLocalTime_WithoutDST()
{
    var utcDateInDstInterval = new DateTime(2012, 07, 15, 0, 0, 0, DateTimeKind.Utc);
    var utcDateOutisdeDstInterval = new DateTime(2012, 02, 15, 0, 0, 0, DateTimeKind.Utc);
    var roTimezone = TimeZoneInfo.FindSystemTimeZoneById("GTB Standard Time");
    var convertedDateWithDst = TimeZoneInfo.ConvertTimeFromUtc(utcDateInDstInterval, roTimezone);
    var convertedDateWithoutDst = TimeZoneInfo.ConvertTimeFromUtc(utcDateOutisdeDstInterval, roTimezone);
    Assert.AreEqual(2, RemoveDSTFromDateTime(convertedDateWithDst, roTimezone).Hour);
    Assert.AreEqual(2, RemoveDSTFromDateTime(convertedDateWithoutDst, roTimezone).Hour);
}
This test also passes, showing that now the effect of DST is cancelled (we always get UTC + 2h, regardless of the time of the year).
While writing this down I got another idea that appears to work: instead of using any TimeZoneInfo.Convert...() methods, simply add roTimezone.BaseUtcOffset to the UTC date.
Can anyone indicate what is the right way to do this?
 
     
     
     
    