Get Current Time in Different Timezone

J

jehugaleahsa

Hello:

I would like it so that the time displayed was always for CDT/CDS.
Potentially, the application can be run at locations in Mountain Time
or Central Time. This is what I have now:

// get the UTC offset depending on day light savings
double hourOffset = DateTime.Now.IsDaylightSavingTime() ? -5 : -6;
DateTimeOffset offset =
DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(hourOffset));

Essentially, is there a way to get the time in a particular timezone
regardless of where the application is run?

Thanks,
Travis
 
C

christery

Hello:

I would like it so that the time displayed was always for CDT/CDS.
Potentially, the application can be run at locations in Mountain Time
or Central Time. This is what I have now:

 // get the UTC offset depending on day light savings
double hourOffset = DateTime.Now.IsDaylightSavingTime() ? -5 : -6;
DateTimeOffset offset =
DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(hourOffset));

Essentially, is there a way to get the time in a particular timezone
regardless of where the application is run?

Thanks,
Travis

I think u need to know where u are,,, and using that knowledge and
accepting that NTP has corrected your clock, dont worry.
OR With user interaction I think that can be a possibility - as in the
user sets the clock right. Without, a GPS would be advisable.
Never heard of mountain time, greenwitch OK but...nah...

//CY
 
J

jehugaleahsa

I think u need to know where u are,,, and using that knowledge and
accepting that NTP has corrected your clock, dont worry.
OR With user interaction I think that can be a possibility - as in the
user sets the clock right. Without, a GPS would be advisable.
Never heard of mountain time, greenwitch OK but...nah...

//CY- Hide quoted text -

- Show quoted text -

Mountain time? Between Central and Pacific? Anyway, human intervention
is not possible.
 
P

Peter Duniho

I would like it so that the time displayed was always for CDT/CDS.
Potentially, the application can be run at locations in Mountain Time
or Central Time. This is what I have now:

// get the UTC offset depending on day light savings
double hourOffset = DateTime.Now.IsDaylightSavingTime() ? -5 : -6;
DateTimeOffset offset =
DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(hourOffset));

Essentially, is there a way to get the time in a particular timezone
regardless of where the application is run?

There's always a way. :)

However, .NET does not, AFAIK, support this directly. It only knows two
timezones: UTC, and your current local timezone. The API actually _looks_
like it could support multiple timezones, if only there were a way to
instantiate a new timezone object according to something other than the
local settings, but I haven't seen anything like that yet.

So you're stuck doing this manually for now. I would hope that in the
future, .NET will include more broad support for timezones, but that
future isn't here yet as far as I know.

By the way, beware of the use of "IsDaylightSavingTime" when creating
DateTime instances outside the local timezone. It will be relative to the
local timezone, which of course may have different daylight saving time
rules than the target timezone.

Pete
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
However, .NET does not, AFAIK, support this directly. It only knows two
timezones: UTC, and your current local timezone. The API actually _looks_
like it could support multiple timezones, if only there were a way to
instantiate a new timezone object according to something other than the
local settings, but I haven't seen anything like that yet.

Fortunately it's available as of .NET 3.5.

See DateTimeOffset (available in .NET 2.0 SP1) and TimeZoneInfo (3.5).
 
J

jehugaleahsa

There's always a way.  :)

However, .NET does not, AFAIK, support this directly.  It only knows two 
timezones: UTC, and your current local timezone.  The API actually _looks_  
like it could support multiple timezones, if only there were a way to  
instantiate a new timezone object according to something other than the  
local settings, but I haven't seen anything like that yet.

So you're stuck doing this manually for now.  I would hope that in the  
future, .NET will include more broad support for timezones, but that  
future isn't here yet as far as I know.

That stinks. I was reading a post somewhere else where they were using
the registry to get all available Timezones. However, I am not sure
how they figured out UTC offsets from that, nor how they handled Day
Light Savings Time. I will just ignore it.
By the way, beware of the use of "IsDaylightSavingTime" when creating  
DateTime instances outside the local timezone.  It will be relative to the  
local timezone, which of course may have different daylight saving time  
rules than the target timezone.

Right. This was my biggest problem with my code. I am going to let it
slide for now, since I can guarantee that the program will be in
Mountain or Central time when run. I don't have to worry about there
being alternate timezone rules within the US, I hope!
 
P

Peter Duniho

[...]
That stinks. I was reading a post somewhere else where they were using
the registry to get all available Timezones. However, I am not sure
how they figured out UTC offsets from that, nor how they handled Day
Light Savings Time. I will just ignore it.

I don't recall the format off the top of my head, but the timezone
database in the registry is not all that complicated. Microsoft has a KB
article on their support web site when US Congress decided on their
pointless changes to the US daylight saving time a couple of years ago,
that not only provided instructions on how to update the timezone database
manually (they didn't have an update available for Windows 2000, if I
recall correctly...I know I needed to update my Windows 2000 computer
manually for some reason), but also included some information that at
least in my case led to knowing a little more about how the data was
stored (I don't recall if the KB article said this explicitly, or if I
just reverse-engineered it by comparing before-and-after archive of the
registry section containing the database).

So if you really needed to, and you're willing to rely on the registry
timezone database, you could in fact take that route.

However, I see from Jon's reply that happy days are here, and that you
only need to upgrade to the latest .NET to get full timezone support. :)
If you can make .NET 3.5 a requirement for your application, I think
that's obviously the way to go.
Right. This was my biggest problem with my code. I am going to let it
slide for now, since I can guarantee that the program will be in
Mountain or Central time when run. I don't have to worry about there
being alternate timezone rules within the US, I hope!

I guess that depends on where in the US the program is being run. The US
definitely does not itself have uniform timezone rules. Hawaii and
Arizona don't do daylight saving at all, and if I recall there's at least
a portion of Indiana that doesn't as well (you obviously could look this
up if you needed specifics...you certainly don't want to rely on my own
recollection for design of your program :) ).

Pete
 
J

jehugaleahsa

Fortunately it's available as of .NET 3.5.

See DateTimeOffset (available in .NET 2.0 SP1) and TimeZoneInfo (3.5).

I was reading about that in my Nutshell book. How great it would be to
live in a 3.5 world!
 
A

Arne Vajhøj

I was reading about that in my Nutshell book. How great it would be to
live in a 3.5 world!

Someone asked about timezone a couple of months ago.

I came up with the following two potential solutions:

public static int GetUTCOffset1(string target)
{
RegistryKey tzs =
Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Windows
NT").OpenSubKey("CurrentVersion").OpenSubKey("Time Zones");
foreach(string tzn in tzs.GetSubKeyNames())
{
if(tzn.Contains(target) ||

((string)tzs.OpenSubKey(tzn).GetValue("Display")).Contains(target))
{
return
-BitConverter.ToInt32((byte[])(tzs.OpenSubKey(tzn).GetValue("TZI")), 0);
}
}
throw new ArgumentException("Unknown timezone " + target);
}
public static int GetUTCOffset2(string target)
{
java.util.TimeZone tz = java.util.TimeZone.getTimeZone(target);
return tz.getRawOffset() / 60000;
}

Arne
 
C

Claes Bergefall

Peter Duniho said:
[...]
That stinks. I was reading a post somewhere else where they were using
the registry to get all available Timezones. However, I am not sure
how they figured out UTC offsets from that, nor how they handled Day
Light Savings Time. I will just ignore it.

I don't recall the format off the top of my head, but the timezone
database in the registry is not all that complicated. Microsoft has a KB
article on their support web site...

You'll find that KB article here:
http://support.microsoft.com/kb/115231

Once you're grabbed all the timezones from the registry you can use
SystemTimeToTzSpecificLocalTime and
TzSpecificLocalTimeToSystemTime to convert betwen UTC and timezone specific
local time

The following code should help:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int SystemTimeToTzSpecificLocalTime(ref
TIME_ZONE_INFORMATION lpTimeZone, ref SYSTEMTIME lpUniversalTIme, out
SYSTEMTIME lpLocalTime);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int TzSpecificLocalTimeToSystemTime(ref
TIME_ZONE_INFORMATION lpTimeZone, ref SYSTEMTIME lpLocalTime, out SYSTEMTIME
lpUniversalTIme);

[StructLayout(LayoutKind.Sequential)]
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}

//Registry time zone format. See KB article Q115231
[StructLayout(LayoutKind.Sequential)]
private struct REG_TIME_ZONE_INFORMATION
{
public int Bias;
public int StandardBias;
public int DaylightBias;
public SYSTEMTIME StandardDate;
public SYSTEMTIME DaylightDate;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct TIME_ZONE_INFORMATION
{
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string StandardName;
public SYSTEMTIME StandardDate;
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DaylightName;
public SYSTEMTIME DaylightDate;
public int DaylightBias;
}

private static List<TIME_ZONE_INFORMATION> GetTimeZones()
{
List<TIME_ZONE_INFORMATION> list = new List<TIME_ZONE_INFORMATION>();
RegistryKey key =
Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Time Zones");
if (key == null)
return list;

string[] subKeyNames = key.GetSubKeyNames();
foreach (string subKeyName in subKeyNames)
{
RegistryKey subKey = key.OpenSubKey(subKeyName);
if (subKey != null)
{
object value = subKey.GetValue("TZI");
if (value != null)
{
int length =
Marshal.SizeOf(typeof(REG_TIME_ZONE_INFORMATION));
IntPtr p = Marshal.AllocHGlobal(length);
Marshal.Copy((byte[])value, 0, p, length);
REG_TIME_ZONE_INFORMATION rtzi =
(REG_TIME_ZONE_INFORMATION)Marshal.PtrToStructure(p,
typeof(REG_TIME_ZONE_INFORMATION));
Marshal.FreeHGlobal(p);

TIME_ZONE_INFORMATION tzi = new TIME_ZONE_INFORMATION();
tzi.Bias = rtzi.Bias;
tzi.DaylightBias = rtzi.DaylightBias;
tzi.StandardBias = rtzi.StandardBias;
tzi.DaylightDate = rtzi.DaylightDate;
tzi.StandardDate = rtzi.StandardDate;
tzi.DaylightName = (string)subKey.GetValue("Dlt", "");
tzi.StandardName = (string)subKey.GetValue("Std", "");
list.Add(tzi);
}
subKey.Close();
}
}
key.Close();
return list;
}


/claes
 

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