Remove DST from DateTime

I saw that many websites (usually forums) allow users to specify their TimeZone settings by choosing:

  • Timezone
  • use or not use DST

As far as I know, when executing transformations. NET always takes into account DST, so the question is:

How can I use the "do not use DST" part in C #?

Below I imagine what I have 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 DST is not applied (for example, in winter), Romanian time is UTC + 2 hours.
  • when DST is applied (for example, in summer), Romanian time is UTC + 3 hours.
  • DateTime DST

TimeZoneInfo.GetAdjustmentRules(), AdjustmentRule , , , DST.

, , , DateTime 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;
}

DST/No DST, 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);
}

, , DST ( UTC + 2h, ).

: - TimeZoneInfo.Convert...() roTimezone.BaseUtcOffset UTC.

- , ?

+5
3

, , :

  • DST -.

  • UTC DateTime BaseUtcOffset, .

, DST, , № 2.

, . , DST, , DST. , , - , , . " ", , .Net TimeZoneInfo , Noda Time.

" ", , TimeZoneInfo.GetSystemTimeZones() ( Id DisplayName), , DST. -, DST (, ), . , , DST (, ).

, IANA/Olson, "America/New York", , Noda Time . DST, .

, , , DST . - , , , , , , . , , , 30 . ? .:)

+4

DST . DST (y/n) . , ( № 2) DST, , , , ( , ). , :

private DateTime RemoveDSTFromDateTime(DateTime dateTime, TimeZoneInfo timeZoneInfo)
{
    #region detail...
    //removes daylight savings time adjustment as defined in current year
    int _currYear = DateTime.Now.Year;

    if (!dateTime.IsDaylightSavingTime())
        return dateTime;

    var result = dateTime;

    foreach (var adjustmentRule in timeZoneInfo.GetAdjustmentRules())
    {
        if (adjustmentRule.DateStart.Year <= _currYear && adjustmentRule.DateEnd.Year >= _currYear)
        {
            result = result.Subtract(adjustmentRule.DaylightDelta);
        }
    }

    return result; 
    #endregion
}
+2

, , - TimeZoneInfo DateTime

myTimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone(
                 TimeZoneInfo.Local.Id,
                 TimeZoneInfo.Local.BaseUtcOffset,
                 TimeZoneInfo.Local.DisplayName,
                 TimeZoneInfo.Local.StandardName, "", null, true);

true, disableDaylightSavingsTime.

:

DateTime noDaylightSavings = TimeZoneInfo.ConvertTimeFromUtc(reading, myTimeZoneInfo);

DateTime noDaylightSavings = TimeZoneInfo.ConvertTimeToUtc(reading, myTimeZoneInfo);
+2

All Articles