How do I convert a DateTime to another time zone?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I would like to know the date and time in another time zone, but I cannot figure out how to do it. For example, I have a DateTime in UTC that is 23:00, which is 18:00 EDT. I would like to know the time in the PDT timezone. Does anyone know which class I should use to do the conversion?
 
Larry,

You are going to have to do this yourself. Unfortunately, you can only
get the TimeZone instance that corresponds to the current system time zone,
not any others (which is foolish in my opinion). You will have to keep a
table of timezones as well as the offsets, and then adjust your date time
instance accordingly.

Hopet this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Larry FAA said:
I would like to know the date and time in another time zone, but I cannot
figure out how to do it. For example, I have a DateTime in UTC that is
23:00, which is 18:00 EDT. I would like to know the time in the PDT
timezone. Does anyone know which class I should use to do the conversion?
 
And it gets worse from there, not every country celebrates Daylight Savings
on the same day as the US.. PLUS - some don't participate at all. So keeping
a database of start and end times would be a mess.. because also consider
many countries have multiple time zones - so you'd almost need to know the
postal code of where you are, to geomap which zone you are in..

Depending on your app, it's best to store everything in UTC/GMT/Zulu 0:00
time.. for DISPLAY purposes, you could just have the user choose what thier
offset is? Or.. if it's on the local machines (which is ideal) - you can
just do .ToLocalTime() to the UTC and it handles it automatically..

HTH

Nicholas Paldino said:
Larry,

You are going to have to do this yourself. Unfortunately, you can only
get the TimeZone instance that corresponds to the current system time zone,
not any others (which is foolish in my opinion). You will have to keep a
table of timezones as well as the offsets, and then adjust your date time
instance accordingly.

Hopet this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Larry FAA said:
I would like to know the date and time in another time zone, but I
cannot
figure out how to do it. For example, I have a DateTime in UTC that is
23:00, which is 18:00 EDT. I would like to know the time in the PDT
timezone. Does anyone know which class I should use to do the conversion?
 
Larry,

I haven't seen any documentation released that indicates that this is
the case. However, there are MS employees that are monitoring these
newsgroups, as well as have comment sections in their personal blogs (the
links of which can be found on msdn.microsoft.com), so if you voice your
concerns, then someone might be listening...


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Larry FAA said:
Nicholas,

Thanks for the answer. I was afraid of that. I looked over the classes
and could not determine which one to use.
Is Microsoft planning to add this in .NET 2.0 ?

-Larry

----- Nicholas Paldino [.NET/C# MVP] wrote: -----

Larry,

You are going to have to do this yourself. Unfortunately, you can only
get the TimeZone instance that corresponds to the current system time zone,
not any others (which is foolish in my opinion). You will have to keep a
table of timezones as well as the offsets, and then adjust your date time
instance accordingly.

Hopet this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Larry FAA said:
I would like to know the date and time in another time zone, but I
cannot
figure out how to do it. For example, I have a DateTime in UTC that is
23:00, which is 18:00 EDT. I would like to know the time in the PDT
timezone. Does anyone know which class I should use to do the conversion?
 
easiest way to do this is to read the registry for the timezone info you want, and pick up the timezone offsets from there.. the reg
entry contains the dates/times at which the change to/from daylight occurs.

-Adrian

I found some code I wrote a while ago that does what you need mostly, just pass a utc date in and convert that instead of Now()
the index passed in relates to an entry id in the registry...
----------------------------------------------------------

Structure SYSTEMTIME
Dim wYear As Short
Dim wMonth As Short
Dim wDayOfWeek As Short
Dim wDay As Short
Dim wHour As Short
Dim wMinute As Short
Dim wSecond As Short
Dim wMilliseconds As Short
End Structure

Private Structure TIME_ZONE_INFORMATION
Dim Bias As Integer
Dim StandardBias As Integer
Dim DaylightBias As Integer
Dim StandardDate As SYSTEMTIME
Dim DaylightDate As SYSTEMTIME
End Structure

Public Shared Sub GetInfo(ByVal aindex As Integer, ByRef TZName As String, ByRef TZDT As String, ByRef adst As Date, ByRef adnd
As Date)

Dim ls_name As String
Dim ls_path As String = "Software\Microsoft\Windows NT\CurrentVersion\Time Zones"
Dim lo_reg As RegistryKey = Registry.LocalMachine.OpenSubKey(ls_path)
Dim lnow As Date
Dim lindex As String

' loop through timezones
For Each ls_name In lo_reg.GetSubKeyNames
Dim tzi As New TIME_ZONE_INFORMATION()
Dim lo_obj As Object
Dim ldayname As String
Dim lstdname As String
Dim lname As String

' get the TZI object for the timezone
Dim lo_subreg As RegistryKey = Registry.LocalMachine.OpenSubKey(ls_path + "\" + ls_name)
If lo_subreg.GetValue("index") = aindex Then
lo_obj = lo_subreg.GetValue("tzi")
TZName = lo_subreg.GetValue("display")

ldayname = lo_subreg.GetValue("dlt")
lstdname = lo_subreg.GetValue("std")
lindex = lo_subreg.GetValue("index").ToString.PadLeft(3, "0")

Dim lbytes() As Byte = CType(lo_obj, Byte())

' populate the TZI struct
Dim lhandle As GCHandle = GCHandle.Alloc(lbytes, GCHandleType.Pinned)
Dim lbuffer As IntPtr = lhandle.AddrOfPinnedObject
tzi = Marshal.PtrToStructure(lbuffer, tzi.GetType)
lhandle.Free()

Dim ldaylightsaving As Boolean = False
Dim ldaydate As Date
Dim lstddate As Date

ldaydate = FindChange(tzi.DaylightDate)
lstddate = FindChange(tzi.StandardDate)
lnow = Now.ToUniversalTime.AddMinutes(tzi.Bias * -1)

adst = ldaydate
adnd = lstddate

lname = lstdname
If ldaydate.Year <> 1900 Then
If lnow < lstddate And lnow > ldaydate Then
lnow = lnow.AddMinutes(tzi.DaylightBias * -1)
lname = ldayname
Else
lnow = lnow.AddMinutes(tzi.StandardBias * -1)
End If
End If

TZDT = lnow.ToString("ddd") + " " + lnow.ToString("h:mm tt")

lo_subreg.Close()
End If

Next
lo_reg.Close()

End Sub

Shared Function FindChange(ByVal st As SYSTEMTIME) As Date
' absolute date change
If st.wYear <> 0 Then
Return New Date(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds)
End If

If st.wMonth = 0 Then Return New Date(1900, 1, 1)

Dim ldate As Date = New Date(Now.Year, st.wMonth, 1, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds)
Dim ldateend As New Date()
ldateend = ldate.AddMonths(1).AddDays(-1)

If ldate.DayOfWeek <> DayOfWeek.Sunday Then
ldate = ldate.AddDays(7 - CInt(ldate.DayOfWeek))
End If
If ldateend.DayOfWeek <> DayOfWeek.Sunday Then
ldateend = ldateend.AddDays(CInt(ldateend.DayOfWeek) * -1)
End If

Select Case st.wDay
Case 1
Return ldate
Case 2
Return ldate.AddDays(7)
Case 3
Return ldate.AddDays(14)
Case 4
Return ldate.AddDays(21)
Case 5
Return ldateend
End Select
End Function

----------------------------------------------------------------------------------------------------------------

Dim ls_tzname As String
Dim ls_tztime As String
Dim ldt_start As Date
Dim ldt_end As Date

GetInfo(3, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_AK.Text = "Alaska"
akst.Text = ls_tztime

GetInfo(4, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_pst.Text = "US West"
pst.Text = ls_tztime

GetInfo(10, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_mst.Text = "US Mountain"
mst.Text = ls_tztime

GetInfo(20, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_cst.Text = "US Central"
cst.Text = ls_tztime

GetInfo(35, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_est.Text = "US East"
est.Text = ls_tztime

GetInfo(85, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_gmt.Text = "United Kingdom"
gmt.Text = ls_tztime

GetInfo(95, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_cet.Text = "Central Europe"
cet.Text = ls_tztime

GetInfo(290, ls_tzname, ls_tztime, ldt_start, ldt_end)
st_nz.Text = "New Zealand"
nzst.Text = ls_tztime
 
This issue is addressed on the Base Class Libraries community site, at
http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/DateTimeFAQ/
FAQ.aspx

====
Does the .NET Framework support Time Zone conversions to any given Time
Zone?

Not in V1.0, V1.1 or the Whidbey pre-release.

The .NET Framework does support conversion to and from UTC and the systems
current local time. It can also support parsing a DateTime from an
arbitrary time zone offset, such as 2003-10-26T13:11:07+10:00, but it must
always convert this either to Local or UTC.

This is a very common feature request and is likely to be in a future
version.

People are often surprised why this feature cannot be supplied by Microsoft
at low cost. In particular, data to do conversions exists in the Windows
registry and is used by the time zone selection dialog. However, there is a
big distinction between having UI and registry data and having an API.

This is a more expensive feature to undertake for Microsoft than most
people would imagine because (a) an API must provide consistent behavior
from one machine to another so we cant just re-expose the registry data and
(b) there is cost for Microsoft in exposing an official Time Zone
conversion because we face on-going geo-political costs for any
country/region based data we gather and maintain. For example, a country
may threaten to boycott our product if they are not listed in the data.
This has happened to us with our CultureInfo data on many occasions, and we
often need to tweak data in service packs, which is expensive and risky.

That being said, there is agreement that this is a very important feature,
and it is under serious consideration for the WinFx release.
====

Katy King
CLR BCL Test


|From: "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
| Larry,
|
| I haven't seen any documentation released that indicates that this is
| the case. However, there are MS employees that are monitoring these
| newsgroups, as well as have comment sections in their personal blogs (the
| links of which can be found on msdn.microsoft.com), so if you voice your
| concerns, then someone might be listening...
|
|
| --
| - Nicholas Paldino [.NET/C# MVP]
| - (e-mail address removed)
|
| | > Nicholas,
| >
| > Thanks for the answer. I was afraid of that. I looked over the classes
| and could not determine which one to use.
| >
| > Is Microsoft planning to add this in .NET 2.0 ?
| >
| > -Larry
| >
| > ----- Nicholas Paldino [.NET/C# MVP] wrote: -----
| >
| > Larry,
| >
| > You are going to have to do this yourself. Unfortunately, you
| can only
| > get the TimeZone instance that corresponds to the current system
time
| zone,
| > not any others (which is foolish in my opinion). You will have to
| keep a
| > table of timezones as well as the offsets, and then adjust your
date
| time
| > instance accordingly.
| >
| > Hopet this helps.
| >
| >
| > --
| > - Nicholas Paldino [.NET/C# MVP]
| > - (e-mail address removed)
| >
| > | > > I would like to know the date and time in another time zone, but
I
| cannot
| > figure out how to do it. For example, I have a DateTime in UTC
that
| is
| > 23:00, which is 18:00 EDT. I would like to know the time in the
PDT
| > timezone. Does anyone know which class I should use to do the
| conversion?
| >
| >
| >
|
|
|
 
Back
Top