daylight savings time mystery

M

Marc Pelletier

Hello,

I am writing an application that does some simple astronomical
calculations. One of the variables I need is the number of hours passed in
this year. I've written the following function

public static double GetHoursofYear( DateTime aTime )
{
DateTime StartYear = new DateTime( aTime.Year, 1, 1 );
return ( aTime.ToOADate() - StartYear.ToOADate() ) * 24;
}

I would expect this function to adapt to daylight savings time but it
doesn't. I'm in Saskatchewan where we don't change, but if I change my
system time zone to Eastern, where they do change I get the same value back
for a given date and time.

In fact I don't want my app to make the adjustment automatically, but I
don't understand why it doesn't!

Thanks for any insight.

Marc Pelletier
 
M

Marc Pelletier

DateTime doesn't know anything about time zones. It just assumes that
all the dates on which you are doing arithmetic are in the same time
zone. See:

http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemdatetimec
lasstopic.asp

Wrong. DateTime is time zone aware because it says in that document that

Methods and properties in this structure always
use the local time zone when making calculations
or comparisons.

and

Time values are measured in 100-nanosecond units
called ticks, and a particular date is the number
of ticks since 12:00 midnight, January 1, 1 A.D.
(C.E.) in the GregorianCalendar calendar


So if the local time zone uses DST then noon on May 1 is one hour
earlier (ie less elapsed time since time zero ) than if the local time
zone doesn't use DST. Since my calculation compares the OATime against
January 1, I expected one hour less when I changed my system to a dst
time zone.

Either the documentation is wrong, or I am dense, because you are
obviously right. The function returns the correct number of hours passed
since the start of the year only if the time passed in hasn't been
adjusted for dst.

Thanks for the help, but I'm still confused.

Marc
 
M

Morten Wennevik

Hi Marc,

You can use

public static double GetHoursofYear( DateTime aTime )
{
DateTime StartYear = new DateTime( aTime.Year, 1, 1 );
double total = (aTime - StartYear).TotalHours;
if(TimeZone.CurrentTimeZone.IsDaylightSavingTime(aTime))
{
DaylightTime dt = TimeZone.CurrentTimeZone.GetDaylightChanges(aTime.Year);
total -= dt.Delta.TotalHours;
}
return total;
}

Happy coding!
Morten Wennevik [C# MVP]
 
G

Guest

Marc said:
I am writing an application that does some simple astronomical
calculations. One of the variables I need is the number of hours passed in
this year. I've written the following function

IMHO the following method is not right because it return the same result
whatever hour in a day you call it:
public static double GetHoursofYear( DateTime aTime )
{
DateTime StartYear = new DateTime( aTime.Year, 1, 1 );
return ( aTime.ToOADate() - StartYear.ToOADate() ) * 24;
}

IMHO, this is the right method:

public static intGetHoursofYear(DateTime aTime)
{
DateTime StartYear = new DateTime(aTime.Year, 1, 1);
TimeSpan t = aTime-StartYear;
return t.Hours;
}
I would expect this function to adapt to daylight savings time but it
doesn't.

Obviously the number of hours passed in this year
does _not_ depend on daylight savings time.
Daylight savings time regards only
the representation of a specific time instance.

- Dario
 
M

Marc Pelletier

=?UTF-8?B?IkRhcmlvIChkcmlua2luZyBjb++sgGVlIGluIHRoZSBv76yDY2XigKYpIg==?=
Obviously the number of hours passed in this year
does _not_ depend on daylight savings time.
Daylight savings time regards only
the representation of a specific time instance.

Well, the number of hours I've lived this year doesn't depend on dst, but
the number of hours between may 1 at noon, and the new year does. In my
case I have a date and time, and if it is during the dst period obviously 1
hour less has passed.

Marc
 
M

Marc Pelletier

if(TimeZone.CurrentTimeZone.IsDaylightSavingTime(aTime))
{
DaylightTime dt =
TimeZone.CurrentTimeZone.GetDaylightChanges(aTime.Year);
total -= dt.Delta.TotalHours;
}

Right, I'm doing something like this, but this is dependent on the time
zone the computer is set for. I'm in Saskatchewan but calculating the
tides in Louisiana ( and elsewhere ), so I determine whether dst applies
the long way.

As I said before, I just don't understand why I have to correct. From the
documentation it seems that the current time zone would affect it
automatically.

cheers

Marc
 
M

Michael A. Covington

quoting the documentation:
Methods and properties in this structure always
use the local time zone when making calculations
or comparisons.

I think they meant to say that it's not aware of time zones at all, i.e.,
what you give it is what you get.
Time values are measured in 100-nanosecond units
called ticks, and a particular date is the number
of ticks since 12:00 midnight, January 1, 1 A.D.
(C.E.) in the GregorianCalendar calendar

Note that no time zone is specified here.
 
G

Greg Miller

Right, I'm doing something like this, but this is dependent on the time
zone the computer is set for. I'm in Saskatchewan but calculating the
tides in Louisiana ( and elsewhere ), so I determine whether dst applies
the long way.

I can't offer any advice for the specific problem you're
having. But for all astronomical computations I recommend using GMT,
then convert to the local time zone when you want to display times to
the user.
Just for fun, a list of all different types of time for
astronomical use:
http://www.ucolick.org/~sla/leapsecs/timescales.html
 
N

news.microsoft.com

Greg:

Good advice; do you use an NTP time source to get the GMT time prior to
adjusting to the local computer?
 
M

Marc Pelletier

=?UTF-8?B?IkRhcmlvIChkcmlua2luZyBjb++sgGVlIGluIHRoZSBv76yDY2XigKYpIg==?=
IMHO the following method is not right because it return the same result
whatever hour in a day you call it:


IMHO, this is the right method:

public static intGetHoursofYear(DateTime aTime)
{
DateTime StartYear = new DateTime(aTime.Year, 1, 1);
TimeSpan t = aTime-StartYear;
return t.Hours;
}


Sorry, I should have responded earlier to this. You are right, yours is
better. Mine was ok because I always start at midnight, but yours is more
elegant and will still work when I don't start at midnight.

cheers

Marc
 

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