title: Remove DST from DateTime
body: <p>I've seen that many websites (usually forums) allow users to specify their TimeZone preferences by selecting:</p>
  <ul>
  <li>the TimeZone</li>
  <li>whether or not to use DST</li>
  </ul>
  <p>As far as I know, when doing conversions, .NET always takes DST into account, so the question is:</p>
  <h3>How can the &quot;do not use DST&quot; part be implemented in C#?</h3>
  <p>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.</p>
  <p>First, to make sure that DST is applied automatically, I wrote the following test:</p>
  
  <pre class="lang-csharp prettyprint-override"><code>[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(&quot;GTB Standard Time&quot;);
  
      Assert.AreEqual(3, TimeZoneInfo.ConvertTimeFromUtc(utcDateInDstInterval, roTimezone).Hour);
      Assert.AreEqual(2, TimeZoneInfo.ConvertTimeFromUtc(utcDateOutisdeDstInterval, roTimezone).Hour);
  }
  </code></pre>
  <p>This test passes, showing that:</p>
  <ul>
  <li>when no DST applies (for example in winter) the Romanian time is UTC + 2 hours</li>
  <li>when DST applies (for example in summer) the Romanian time is UTC + 3 hours</li>
  <li>when doing DateTime conversions, DST is automatically taken into account</li>
  </ul>
  <p>Next, I noticed the <a href="http://msdn.microsoft.com/en-us/library/system.timezoneinfo.getadjustmentrules%28v=vs.100%29.aspx" rel="noreferrer"><code>TimeZoneInfo.GetAdjustmentRules()</code></a> method that returns an array of <a href="http://msdn.microsoft.com/en-us/library/system.timezoneinfo.adjustmentrule%28v=vs.100%29.aspx" rel="noreferrer"><code>AdjustmentRule</code></a> objects and figured out that if I undo the effects of these rules I could get the DST-unaffected value.</p>
  <p>So I wrote the following method that does this if the <code>DateTime</code> object <a href="http://msdn.microsoft.com/en-us/library/system.datetime.isdaylightsavingtime%28v=vs.100%29.aspx" rel="noreferrer">is affected by DST</a>:</p>
  <pre class="lang-csharp prettyprint-override"><code>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;
  }
  </code></pre>
  <p>Back to the original DST/No DST scenario, but this time forcing the result to be unaffected by DST:</p>
  <pre class="lang-csharp prettyprint-override"><code>[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(&quot;GTB Standard Time&quot;);
  
      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);
  }
  </code></pre>
  <p>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).</p>
  <p>While writing this down I got another idea that appears to work: instead of using any <code>TimeZoneInfo.Convert...()</code> methods, simply add <code>roTimezone.BaseUtcOffset</code> to the UTC date.</p>
  <p>Can anyone indicate what is the right way to do this?</p>