views:

2485

answers:

5

Regardless of what the user's local time zone is set to, using C# (.NET 2.0) I need to determine the time (DateTime object) in the Eastern time zone.

I know about these methods but there doesn't seem to be an obvious way to get a DateTime object for a different time zone than what the user is in.

 DateTime.Now
 DateTime.UtcNow
 TimeZone.CurrentTimeZone

Of course, the solution needs to be daylight savings time aware.

A: 

How about

 DateTime lclTime = DateTime.Now;
 DateTime ept = lclTime.ToUniversalTime().AddHours(
                   IsEasternDaylightSavingTime(
                       lclTime.ToUniversalTime())? -5: -4)

or if you already have local UTC, just

 DateTime lclUtc = DateTime.UtcNow;
 DateTime ept = lclUtc.AddHours(
                  IsEasternDaylightSavingTime(lclUtc)? -5: -4)

Use static dictionary of hard coded values for Spring-forward and fall back dates for Eastern time for the next 50 years.. That's only 300 bytes or so... and then index into that to determine whether it's Daylight savings time on east coast... As pointed out, you don;t care whether it's dST in local zone or not...

 private static bool IsEasternDaylightSavingTime(DateTime utcDateTime)
   {
        // hard coded method to determine 
        // whether utc datetime is Eastern Standard time
        // or Eastern Daylight Time
   }
Charles Bretana
What if your location does not use DST? Then IsDaylightSavingTime will return false.
Jon B
UTC won't be affected by DST; surely it is the Eastern's DST we need to know, not locals.
Marc Gravell
Got me... I don't know if you can create a timezone object for a different timezone that the one the computer is set to. And you'd have t ocreate a timezone object fpr Eastern time to determin whether it's DST there or not...
Charles Bretana
+7  A: 

In .NET 3.5, there is TimeZoneInfo, which provides a lot of functionality in this area; 2.0SP1 has DateTimeOffset, but this is much more limited.

Getting UtcNow and adding a fixed offset is part of the job, but isn't DST-aware.

So in 3.5 I think you can do something like:

DateTime eastern = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(
    DateTime.UtcNow, "Eastern Standard Time");

But this simply doesn't exist in 2.0; sorry.

Marc Gravell
Even though he wasn't within the OP's constraints, he answered MY question, so I modded this up :)
Chris
+1  A: 

From - http://msdn.microsoft.com/en-us/library/system.timezoneinfo.converttimefromutc.aspx

This allows a time zone to be found by name, in case the US ever floats 15 degrees west or east from the London meridian.

DateTime timeUtc = DateTime.UtcNow;
try
{
   TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
   DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
   Console.WriteLine("The date and time are {0} {1}.", 
                     cstTime, 
                     cstZone.IsDaylightSavingTime(cstTime) ?
                             cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Central Standard Time zone.");
}                           
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Central STandard Time zone has been corrupted.");
}
Christopher Edwards
+1  A: 

I'll save you the time and tell you that there is no way in .net proper, version 2.0 to get a DateTime object for another time zone different from the one that the software is running on (other than UTC).

However, that doesn't mean there isn't a way to do it outside of .net. Take a look here at the TimeZoneInformation class. This class wraps some p/invoke stuff to the Win O/S to get the time zone information from the O/S. I successfully used it back when 2.0 was new and it worked very well. The site I was working on had to be able to show every date/time local to the user and had to be DST-aware, and this class filled the bill for us.

Robert C. Barth
+3  A: 

As everyone else mentioned, .NET 2 doesn't contain any time zone information. The information is stored in the registry, though, and its fairly trivial to write a wrapper class around it:

SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

contains sub-keys for all time zones. The TZI field value contains all the transition and bias properties for a time zone, but it's all stuffed in a binary array. The most important bits (bias and daylight), are int32s stored at positions 0 and 8 respectively:

int bias = BitConverter.ToInt32((byte[])tzKey.GetValue("TZI"), 0);
int daylightBias = BitConverter.ToInt32((byte[])tzKey.GetValue("TZI"), 8);

This page has a reasonable summary: http://burks.brighton.ac.uk/burks/language/pascal/uddf/pages/registry.htm

Andy