Updated to version: 1.0.0.2
A 
Time Zone is a region that has a uniform standard time for legal, commercial, and social purposes. It is convenient for areas in close commercial or other communication to keep the same time, so time zones tend to follow the boundaries of countries and their subdivisions.
The code snippet proposed here can be used to 
finding TimeZone by geographical coordinate Latitude / Longitude using a TimeZone Shapefile database on .NET framework
The TimeZone shapefile used for conversion is:
All the library used are open source, also you can find License for those library inside the sample project attached to this post:
At first we need to load all the Geometries contained in the shapefile, and the TimeZone associated, we build a structure used as the container for all data:
private List<GetTimeZones> m_geotimezones = new List<GetTimeZones>();
private class GetTimeZones
{
  public string timezone { get; set; }
  public GeoAPI.Geometries.IGeometry[] geometry { get; set; }
}
 
Then we load all the data to this container:
public FindTimeZoneByLocation(string shapeFileName)
{
  try
  {
    List<NetTopologySuite.Features.Feature> featureCollection = new List<NetTopologySuite.Features.Feature>();
    //built feature collection from shapefile
    NetTopologySuite.IO.ShapefileDataReader dataReader = new NetTopologySuite.IO.ShapefileDataReader(shapeFileName, new NetTopologySuite.Geometries.GeometryFactory());
    while (dataReader.Read())
    {
      //read current feature
      NetTopologySuite.Features.Feature feature = new NetTopologySuite.Features.Feature();
      feature.Geometry = dataReader.Geometry;
      //get feature keys
      int length = dataReader.DbaseHeader.NumFields;
      string[] keys = new string[length];
      for (int i = 0; i < length; i++)
        keys[i] = dataReader.DbaseHeader.Fields[i].Name;
      //get features attributes
      feature.Attributes = new NetTopologySuite.Features.AttributesTable();
      for (int i = 0; i < length; i++)
      {
        object val = dataReader.GetValue(i);
        feature.Attributes.AddAttribute(keys[i], val);
      }
      //add feature to collection
      featureCollection.Add(feature);
    }
    
    GeoAPI.Geometries.IGeometryFactory gf = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory();
    //built timezones array
    foreach (NetTopologySuite.Features.Feature feature in featureCollection)
    {
      try
      {
        //get timezone
        NetTopologySuite.Features.AttributesTable table = (NetTopologySuite.Features.AttributesTable)feature.Attributes;
        string timezone = table["TZID"].ToString();
        //set getometry
        GeoAPI.Geometries.IGeometry geometry = feature.Geometry;
        bool addnew = true;
        foreach (GetTimeZones geotimezone in m_geotimezones)
        {
          //add geometry to existing timezone
          if (geotimezone.timezone.CompareTo(timezone) == 0)
          {
            addnew = false;
            geotimezone.geometry = geotimezone.geometry.Concat<GeoAPI.Geometries.IGeometry>(new[] { geometry }).ToArray();
          }
        }
        //add a new timezone and his first geometry
        if (addnew)
        {
          GetTimeZones addgeotimezone = new GetTimeZones();
          addgeotimezone.timezone = timezone;
          addgeotimezone.geometry = new[] { geometry };
          m_geotimezones.Add(addgeotimezone);
        }
      }
      catch { }
    }            
  }
  catch { }
}
 
Then the function that finds if a point, given by latitude / longitude, it also search for the points at a given distance it the exact point is not found, this is usefull for location next to the sea.
public string GetIanaTZName(double latitude, double longitude)
{
  string ret = "";
  
  //make search point
  GeoAPI.Geometries.Coordinate point = new GeoAPI.Geometries.Coordinate(longitude, latitude);
  //loop through zones and search for a point insize the zone
  foreach (GetTimeZones geotimezone in m_geotimezones)
  {
    foreach (GeoAPI.Geometries.IGeometry geometry in geotimezone.geometry)
    {
      try
      {
        if(NetTopologySuite.Algorithm.Locate.SimplePointInAreaLocator.Locate(point, geometry).Equals(GeoAPI.Geometries.Location.Interior))
        {
          ret = geotimezone.timezone;
          return ret;
        }
      }
      catch { }
    }
  }
  
  double distance = 0;
  //set search distance for unfound point
  distance = 0.01;
  if (ret == "")
  {
    foreach (GetTimeZones geotimezone in m_geotimezones)
    {
      foreach (GeoAPI.Geometries.IGeometry geometry in geotimezone.geometry)
      {
        try
        {
          NetTopologySuite.Algorithm.Distance.PointPairDistance ptdist = new NetTopologySuite.Algorithm.Distance.PointPairDistance();
          NetTopologySuite.Algorithm.Distance.DistanceToPoint.ComputeDistance(geometry, point, ptdist);
          if (ptdist.Distance < distance)
          {
            ret = geotimezone.timezone;
            return ret;
          }
        }
        catch { }
      }
    }
  }
  return ret;
}
 
Changelog
- 1.0.0.2: added the IanaToWindows Timezone Id converter
- 1.0.0.1: first release
 
Code
Notes
- read risk disclaimer
- excuse my bad english