1

I am trying to get local time based on latitude and longitude from Google TimeZone API. I'm using RestSharp to obtain my data. Here's my code:

public class GoogleTimeZone
{
    public double dstOffset { get; set; }
    public double rawOffset { get; set; }
    public string status { get; set; }
    public string timeZoneId { get; set; }
    public string timeZoneName { get; set; }
}

public static DateTime GetLocalDateTime(double latitude, double longitude, DateTime date)
{
    var client = new RestClient("https://maps.googleapis.com");
    var request = new RestRequest("maps/api/timezone/json", Method.GET);
    request.AddParameter("location", latitude + "," + longitude);
    request.AddParameter("timestamp", date.ToTimestamp());
    var response = client.Execute<GoogleTimeZone>(request);

    return date.AddSeconds(response.Data.rawOffset + response.Data.dstOffset);
}

public static class DateTimeExtentionMethods
{
    public static double ToTimestamp(this DateTime date)
    {
        return date.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
    }
}

When I ran the following code:

// Algeria
var myDateTime = GetLocalDateTime(29.204918, 1.845703, DateTime.Now);
Console.WriteLine(myDateTime.ToString());

// California
myDateTime = GetLocalDateTime(34.020084, -118.182678, DateTime.Now);
Console.WriteLine(myDateTime.ToString());

...I got the following output:

8/5/2014 6:18:22 PM
8/5/2014 10:18:22 AM

First one is for Algeria and the second one is for California. However, that is way off. The time for Algeria was supposed to be 1:18:22 AM on August 6 and the current time for California was supposed to be 5:18:22 PM on August 5.

When I checked the time zones of the returned data, it matched the regions in question. I also checked the UTC timestamp that's being passed and it's correct. Therefore, I am not sure what the error in my code is.

EDIT:

This is incredibly odd... my code runs as intended on .NET Fiddle: https://dotnetfiddle.net/lPKJ5Q.

B.K.
  • 9,418
  • 9
  • 64
  • 98

1 Answers1

3

Figured out what was wrong thanks to some fellas on #csharp @ freedone.net (especially Suchiman). In the GetLocalDateTime method this line is the one that caused all the problems:

return date.AddSeconds(response.Data.rawOffset + response.Data.dstOffset);

It was adding the raw and daylight savings offsets to the local time, instead of UTC time.

Here's the new code:

public static DateTime GetLocalDateTime(double latitude, double longitude, DateTime date)
{
    date = date.ToUniversalTime(); // Convert to UTC
    var client = new RestClient("https://maps.googleapis.com");
    var request = new RestRequest("maps/api/timezone/json", Method.GET);
    request.AddParameter("location", latitude + "," + longitude);
    request.AddParameter("timestamp", date.ToTimestamp());
    request.AddParameter("sensor", "false");
    var response = client.Execute<GoogleTimeZone>(request);

    return date.AddSeconds(response.Data.rawOffset + response.Data.dstOffset);
}

...and of course, we can get rid of the UTC conversion in the ToTimeStamp extension method.

As far as to why it worked on .NET Fiddle... it could be due to the fact that because their server is making the request, it's probably in UTC time, so I was getting appropriate results, while they were actually erroneous.

B.K.
  • 9,418
  • 9
  • 64
  • 98