WP7: TimeZone Info and how to Get It

timeUnlike on the desktop, Silverlight for Windows Phone only provides local and UTC time zone information. I had a requirement for a stock trading application to display all of the transaction times in Eastern time. The difficulty was determining if Daylight Savings Time was in effect or not. On the desktop TimeZoneInfo supports all of the time zones supported in Windows 7, so this is very straight forward.

On Windows Phone, we considered using a rule based on dates, but of course this would break ff the daylight savings rules ever change, which they do from time to time. The following is a solution using the GeoNames service. GeoNames has several geo-location related web services including time zone. (GeoNames is free for up to 30K requests per day. They have a variety of pay plans offering various requests and response times.)

The time zone web service returns the current time zone information for a given latitude, longitude pair. In a nutshell to display transaction times in Eastern time, you apply the East Coast time zone offset returned by GeoNames to the stored UTC value. Code below:

private void button1_Click(object sender, RoutedEventArgs e)
{
    // get account at http://www.geonames.org/ 30K requests / username / day limit.
    // get current timezone info for NYC
    var txtURL = new Uri(http://api.geonames.org/timezone?lat=40.71417&lng=-74.00639&username=demo1);
    var request = (HttpWebRequest)WebRequest.Create(txtURL);
    string responseString = "";
    request.Method = "GET";
    request.BeginGetResponse(a =>
    {
        var response = request.EndGetResponse(a);
        var responseStream = response.GetResponseStream();
        using (var sr = new StreamReader(responseStream))
        {
            using (StreamReader reader = new StreamReader(responseStream))
            {
                DateTime t1 = new DateTime();
                try
                {
                    responseString = reader.ReadToEnd();
                    Debug.WriteLine(responseString);

                    // Get dst offset for NYC
                    XDocument doc = XDocument.Parse(responseString);
                    var dstOffset = GetTime(doc, "dstOffset");
                    var offset = Convert.ToDouble(dstOffset);

                    // Convert local current time to UTC - we will display this in NYC time.
                    var t = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Utc);
                    // apply offset to adjust current utc time to East Coast Time.
                    t1 = t.AddHours(offset);
                }
                catch (Exception ex)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        if (ex.Message == "NullReferenceException")
                        {
                            XDocument doc = XDocument.Parse(responseString);
                            var statusMessage = doc.Descendants("status");
                            var q = from c in statusMessage
                                    select c;
                            var en = q.GetEnumerator();
                            en.MoveNext();
                            MessageBox.Show(en.Current.Attribute("message").Value.ToString());
                            return;
                        }
                        else
                        {
                            MessageBox.Show(responseString);
                        }
                        return;
                    });
                }

                Dispatcher.BeginInvoke(() =>
                {
                    localt.Text = DateTime.Now.ToString();
                    ect.Text = t1.ToString();
                });
            }
        }
    }, null);

}

string GetTime(XDocument doc, string element)
{
    var q = from c in doc.Descendants(element)
            select c;
    var en = q.GetEnumerator();
    var t = en.MoveNext();
    return en.Current.Value;
}

You can download a complete sample here.

Thanks,

Mike

Leave a Reply

Your email address will not be published. Required fields are marked *