I'm developing an newsletter sending application on C#/.NET platform. I've recently added the module to retrieve the country and region of a recipient by his IP address using maxmind.com database.
For example, I can get the following info for some sample IP address:
Country Code: DE
Country Name: Germany
Region Name: Hessen
City: Frankfurt Am Main
Latitude: 50.1167
Longitude: 8.6833
What I need now is to get the user's time zone using this information.
I know there are some GeoIp databases that provide also the time zone, but I need to use this concrete GeoIp database. Also, javascript's approach to determine time offset can't be used here.
May be I can get somehow the timezone using country and region name?
Some countries have more as one timezone for example Russia.
In my solution i use NodaTime you can use your longitude information from maxmind to find the best match.
var countryName = "Russia";
var longitude = 40.332206;
var zones = TzdbDateTimeZoneSource.Default.ZoneLocations.Where(x => x.CountryName == countryName).AsQueryable();
if (!double.IsNaN(longitude))
{
//If a longitude available use the information to order the zones by distance
zones = zones.OrderBy(o => this.Distance(o.Latitude, longitude, o.Latitude, o.Longitude, DistanceUnit.Kilometer));
}
var bestZone = zones.FirstOrDefault();
var dateTimeZone = TzdbDateTimeZoneSource.Default.ForId(bestZone.ZoneId);
var newTime = DateTime.UtcNow.AddSeconds(dateTimeZone.MaxOffset.Seconds);
Calculate distance of geo coordinates
public enum DistanceUnit { StatuteMile, Kilometer, NauticalMile };
private double Distance(double lat1, double lon1, double lat2, double lon2, DistanceUnit unit)
{
double rlat1 = Math.PI * lat1 / 180;
double rlat2 = Math.PI * lat2 / 180;
double theta = lon1 - lon2;
double rtheta = Math.PI * theta / 180;
double dist =
Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
Math.Cos(rlat2) * Math.Cos(rtheta);
dist = Math.Acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
switch (unit)
{
case DistanceUnit.Kilometer:
return dist * 1.609344;
case DistanceUnit.NauticalMile:
return dist * 0.8684;
default:
case DistanceUnit.StatuteMile:
return dist;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With