Getting the change from Daylight Savings time to Standard time.


S

Sonnich Jensen

Hi

We do this twice a year, but in the autum, we turn our clocks back,
and usually the hour 2 or 3 repeats itself.
This is a problem for a data handler of my, which should not do this
when the hour happens the first time.

I an older Delphi version, I used GetTimeZoneInformation to get to
know whether we have daylight savings time or standard (winter) time.
This works also in the code below, which btw currently is for testing
only.
When I know that I have daylight savings time (if is missing below),
I'd like to know when the change happens.
In Delphi I just set the years, and they would be there.
I digged into Delphi how that happens, but did not find it.

Now, how do I know when the change over happens?

WBR
Sonnich


My code as of now:


[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet =
CharSet.Unicode)]
public struct TimeZoneInformation
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SYSTEMTIME standardDate;
public SYSTEMTIME daylightDate;
public int standardBias;
public int daylightBias;
}

const uint TIME_ZONE_ID_INVALID = 0xFFFFFFFF;
const uint TIME_ZONE_ID_UNKNOWN = 0;
const uint TIME_ZONE_ID_STANDARD = 1;
const uint TIME_ZONE_ID_DAYLIGHT = 2;

// ********** check for daylight savings time *************
bool Daylight()
{
TimeZoneInformation TZI = new TimeZoneInformation();
short myyear = (short)DateTime.Now.Year;
TZI.standardDate.wYear = myyear;
TZI.daylightDate.wYear = myyear;

// true = we have daylight savings time
bool bDaylight = (GetTimeZoneInformation(ref TZI) ==
TIME_ZONE_ID_DAYLIGHT);

// *** this should set the time so I know the time when it actuallty
happend, but that does not work here...
TZI.standardDate.wYear = myyear;
TZI.daylightDate.wYear = myyear;
// check for repeated hour
// **** and I cannot remember why I checkc Month==0 ... I should
comment my software a bit more...
if ((TZI.standardDate.wMonth != 0) && // 0= no time
change
((DateTime.Now.Month == TZI.standardDate.wMonth) &&
(DateTime.Now.Day == TZI.standardDate.wDay)))
{
// if it is that very hour (the repeated hour)
return (DateTime.Now.Hour != (TZI.standardDate.wHour -
1));
}
return true;
}
 
Ad

Advertisements

S

Sonnich Jensen

Hi

We do this twice a year, but in the autum, we turn our clocks back,
and usually the hour 2 or 3 repeats itself.
This is a problem for a data handler of my, which should not do this
when the hour happens the first time.

I an older Delphi version, I used GetTimeZoneInformation to get to
know whether we have daylight savings time or standard (winter) time.
This works also in the code below, which btw currently is for testing
only.
When I know that I have daylight savings time (if is missing below),
I'd like to know when the change happens.
In Delphi I just set the years, and they would be there.
I digged into Delphi how that happens, but did not find it.

Now, how do I know when the change over happens?

WBR
Sonnich

My code as of now:

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern int GetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern bool SetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }
        [StructLayout(LayoutKind.Sequential, CharSet =
CharSet.Unicode)]
        public struct TimeZoneInformation
        {
            public int bias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst =32)]
            public string standardName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst =32)]
            public string daylightName;
            public SYSTEMTIME standardDate;
            public SYSTEMTIME daylightDate;
            public int standardBias;
            public int daylightBias;
        }

        const uint TIME_ZONE_ID_INVALID = 0xFFFFFFFF;
        const uint TIME_ZONE_ID_UNKNOWN = 0;
        const uint TIME_ZONE_ID_STANDARD = 1;
        const uint TIME_ZONE_ID_DAYLIGHT = 2;

        // ********** check for daylight savings time *************
        bool Daylight()
        {
            TimeZoneInformation TZI = new TimeZoneInformation();
            short myyear = (short)DateTime.Now.Year;
            TZI.standardDate.wYear = myyear;
            TZI.daylightDate.wYear = myyear;

            // true = we have daylight savings time
            bool bDaylight = (GetTimeZoneInformation(ref TZI) ==
TIME_ZONE_ID_DAYLIGHT);

 // *** this should set the time so I know the time when it actuallty
happend, but that does not work here...
            TZI.standardDate.wYear = myyear;
            TZI.daylightDate.wYear = myyear;
            // check for repeated hour
// **** and I cannot remember why I checkc Month==0 ... I should
comment my software a bit more...
            if ((TZI.standardDate.wMonth != 0) && // 0= no time
change
                ((DateTime.Now.Month == TZI.standardDate.wMonth) &&
                 (DateTime.Now.Day == TZI.standardDate.wDay)))
            {
                // if it is that very hour (the repeated hour)
                return (DateTime.Now.Hour != (TZI.standardDate.wHour -
1));
            }
            return true;
        }

I searched a bit more and came up with:

// ********** check for daylight savings time *************
bool Daylight()
{
TimeZone localZone = TimeZone.CurrentTimeZone;
// true = we have daylight savings time
bool bDaylight =
localZone.IsDaylightSavingTime(DateTime.Now);
if (!bDaylight)
return true;

// Get the DaylightTime object for the current year.
DaylightTime daylight =
localZone.GetDaylightChanges(myyear);

// check for repeated hour
return (daylight.End.Month == 0) || // 0= no time change
!((daylight.End.Month == DateTime.Now.Month) &&
(daylight.End.Day == DateTime.Now.Day) &&
((daylight.End.Hour - 1) == DateTime.Now.Hour));
}

It will return true, if is safe. It will only return false in the last
hour of daylight savings time

Sonnich
 
Ad

Advertisements

A

Arne Vajhøj

We do this twice a year, but in the autum, we turn our clocks back,
and usually the hour 2 or 3 repeats itself.
This is a problem for a data handler of my, which should not do this
when the hour happens the first time.

I an older Delphi version, I used GetTimeZoneInformation to get to
know whether we have daylight savings time or standard (winter) time.
This works also in the code below, which btw currently is for testing
only.
When I know that I have daylight savings time (if is missing below),
I'd like to know when the change happens.
In Delphi I just set the years, and they would be there.
I digged into Delphi how that happens, but did not find it.

Now, how do I know when the change over happens?

WBR
Sonnich

My code as of now:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation(ref
TimeZoneInformation lpTimeZoneInformation);
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet =
CharSet.Unicode)]
public struct TimeZoneInformation
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SYSTEMTIME standardDate;
public SYSTEMTIME daylightDate;
public int standardBias;
public int daylightBias;
}

const uint TIME_ZONE_ID_INVALID = 0xFFFFFFFF;
const uint TIME_ZONE_ID_UNKNOWN = 0;
const uint TIME_ZONE_ID_STANDARD = 1;
const uint TIME_ZONE_ID_DAYLIGHT = 2;

// ********** check for daylight savings time *************
bool Daylight()
{
TimeZoneInformation TZI = new TimeZoneInformation();
short myyear = (short)DateTime.Now.Year;
TZI.standardDate.wYear = myyear;
TZI.daylightDate.wYear = myyear;

// true = we have daylight savings time
bool bDaylight = (GetTimeZoneInformation(ref TZI) ==
TIME_ZONE_ID_DAYLIGHT);

// *** this should set the time so I know the time when it actuallty
happend, but that does not work here...
TZI.standardDate.wYear = myyear;
TZI.daylightDate.wYear = myyear;
// check for repeated hour
// **** and I cannot remember why I checkc Month==0 ... I should
comment my software a bit more...
if ((TZI.standardDate.wMonth != 0)&& // 0= no time
change
((DateTime.Now.Month == TZI.standardDate.wMonth)&&
(DateTime.Now.Day == TZI.standardDate.wDay)))
{
// if it is that very hour (the repeated hour)
return (DateTime.Now.Hour != (TZI.standardDate.wHour -
1));
}
return true;
}

I searched a bit more and came up with:

// ********** check for daylight savings time *************
bool Daylight()
{
TimeZone localZone = TimeZone.CurrentTimeZone;
// true = we have daylight savings time
bool bDaylight =
localZone.IsDaylightSavingTime(DateTime.Now);
if (!bDaylight)
return true;

// Get the DaylightTime object for the current year.
DaylightTime daylight =
localZone.GetDaylightChanges(myyear);

// check for repeated hour
return (daylight.End.Month == 0) || // 0= no time change
!((daylight.End.Month == DateTime.Now.Month)&&
(daylight.End.Day == DateTime.Now.Day)&&
((daylight.End.Hour - 1) == DateTime.Now.Hour));
}

It will return true, if is safe. It will only return false in the last
hour of daylight savings time

I don't understand all that complicated code.

DateTime IsDaylightSavingTime should work fine, if the DateTime
is correct.

Example:

using System;
using System.Threading;

namespace E
{
public class Program
{
public static void Dump(DateTime dt)
{
Console.WriteLine("local " + dt + " = UTC " +
dt.ToUniversalTime() + " : " + dt.IsDaylightSavingTime());
}
public static void Main(string[] args)
{
DateTime dt = new DateTime(2011, 11, 6, 0, 0, 0,
DateTimeKind.Local); // one hour before change - example is fall eastern US
Dump(dt.AddHours(0).AddMinutes(30));
Dump(dt.AddHours(1).AddMinutes(30));
Dump(dt.AddHours(2).AddMinutes(30));
Dump(dt.AddHours(3).AddMinutes(30));
DateTime dt2 = dt.ToUniversalTime();
Dump(dt2.AddHours(0).AddMinutes(30).ToLocalTime());
Dump(dt2.AddHours(1).AddMinutes(30).ToLocalTime());
Dump(dt2.AddHours(2).AddMinutes(30).ToLocalTime());
Dump(dt2.AddHours(3).AddMinutes(30).ToLocalTime());
Console.ReadKey();
}
}
}

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top