Question

This question already has an answer here:

As the title infers I need to find a time zone (or perhaps just the UTC offset) based on a pair of coordinates. I've been searching for different solutions, and there is a couple of web services out there but I need to be able to access the application offline. As the timezones isn't completely based on longitude it doesn't seem that easy...

I though about querying an ESRI shapefile I've got containing all the countries in world and their timezones, but it seems kind of complex. If that should be the solution, do you know of any .NET library providing this functionality?

OTHER TIPS

I have solved this with a client application. The technique was to make a color-coded cylindrical map of the world, each time zone has a unique color. Lat-Lons are converted to picture co-ordinates and the color of the co-ordinate is read then cross-referenced to the timezone of that color.

That short explaination isn't exactly what I did but it gets the idea across. I actually populated a couple dictionaries and did lookup from them. The first rendition took 2M of resource file to populate (after I processed my map and turned it into binary data). The theoretical max error (for latitudes near the equator) should have been +/- about 15 miles. Unfortunately my starting map's accuracy was more like +/- 100 miles.

So I'm redoing the project. I've been into it several days now creating a both more accurate and higher-rez map to crunch. A couple more days and it should be done. The resource file will be around 20M unless I choose only to resource the "goofy areas" and mathematically compute the 90% of the world that can be calculated directly (most of the world's can be mathematically derived from longitude). Not sure many would care that a resource file was 20M but some might. At any rate, if there seems to be some interest, I'll try to post the code necessary to run it here and the resource file one one of the public code sites. If there seems to be no interest, I won't bother.

Just to re-iterate a bit, the code necessary in your app is only a few lines, but the resource file is big (w/o shrinking it, my new one is running 22M). It is also fast (the first rendition ran 100M / sec). It DOES require a file load and that takes a little time. The 2M version had no noticeable delay but 22M might (not there yet).

Check the tz database. I know it associates names to timezones (like city, countries, EST, etc). But I believe there is an extension for coordinates somewhere.

I've tried to export the table but it doesn't seem possible to export geometry types to text .. however it wasn't that hard to do anyway.. You need to google the shapefile Manifold produced a few years ago which maps all the contries in the world and their timezones.. Then you need to export that data to SQL Server 2008 using some program.. I used Manifold (remember to use Enterprise Edition or above).. Then I query the data using the following stored procedure:

USE [MyDb]
GO
/****** Object:  StoredProcedure [dbo].[GetTimeZone]    Script Date: 11/18/2009 21:23:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetTimeZone]
    @Latitude float,
    @Longitude float
AS
    /* SET NOCOUNT ON */

DECLARE @g geometry

/* Validation */
IF @Latitude > 90 OR @Latitude < -90 OR @Longitude > 180 OR @Longitude < -180
    RAISERROR('Latitude or longitude out of range', 16, 1)

IF @Latitude IS NULL OR @Longitude IS NULL
    RAISERROR('Latitude or longitude cannot be null', 16, 1)

SET @g = geometry::Point(@Longitude, @Latitude, 4326);

IF EXISTS(SELECT * From TimeZones WHERE Shape.STContains(@g) = 1)
    /* Point exists on map, get the info */
    SELECT Name, LocalSumme, Offset, AreaI FROM TimeZones WHERE Shape.STContains(@g) = 1
ELSE
    /* Point is an international water */
    IF(@Longitude >= 0)
        SELECT NULL AS Name, NULL AS LocalSumme, FLOOR((@Longitude + 7.5) / 15) AS Offset, NULL AS AreaI
    ELSE
        SELECT NULL AS Name, NULL AS LocalSumme, -FLOOR((-@Longitude + 7.5) / 15) AS Offset, NULL AS AreaI

There's a problem in the shapefile because national waters isn't mapped. I though of maybe using @g.STBuffer() to address this problem..

The solution was to export an ESRI shapefile to SQL Server 2008 using the new spatial datatypes.

If anyone has a better solution feel free to post!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top