C# - Get time zone and UTC offset from latitude and longitude (GPS coordinates)
I recently set up an Instagram feed for a travel blog and found that the Instagram API only supplies the UTC created date/time of each image, and doesn't supply the user's UTC Offset (as the Twitter API does), so the only thing you have to work with are the latitude and longitude (lat/long) coordinates to find out the timezone and UTC Offset of where the image was posted.
I'm sure I remember searching for a solution to this problem a few times over the years without much luck, there were only ever a few commercial options available and none were cheap, whereas I was looking for a free option. Luckily Google has come to the rescue with the recent release of The Google Time Zone API. It does exactly what I needed, it exposes a REST API that accepts parameters for lat/long coordinates and a timestamp (to determine if it's daylight savings time at the location) and returns the timezone and UTC Offset information for the location, either as JSON or XML.
An example request looks like:
https://maps.googleapis.com/maps/api/timezone/json?location=43.29712312,5.382137115×tamp=1374868635&sensor=false
and returns the response:
{
"dstOffset" : 3600.0,
"rawOffset" : 3600.0,
"status" : "OK",
"timeZoneId" : "Europe/Paris",
"timeZoneName" : "Central European Summer Time"
}
UPDATE: A fiddle for the below code can be found at https://dotnetfiddle.net/dMEtfP.
I used the RestSharp library to enable easy access the API, it's available on NuGet. Here's my C# code for getting the timezone info for a location:
public DateTime GetLocalDateTime(double latitude, double longitude, DateTime utcDate)
{
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", utcDate.ToTimestamp());
request.AddParameter("sensor", "false");
var response = client.Execute<GoogleTimeZone>(request);
return utcDate.AddSeconds(response.Data.rawOffset + response.Data.dstOffset);
}
This method is called with lat/long coordinates and the current UTC time like so:
var myDateTime = GetLocalDateTime(33.8323, -117.8803, DateTime.UtcNow);
Here's the code for the GoogleTimeZone class that I used as a wrapper for the JSON response from the Google Time Zone API:
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; }
}
And lastly the extension method for converting a C# DateTime object to a Timestamp:
public static double ToTimestamp(this DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date.ToUniversalTime() - origin;
return Math.Floor(diff.TotalSeconds);
}
Need Some C# Help?
Search fiverr for freelance C# developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!
More C# Posts
- .NET 7.0 + MySQL - Connect to MySQL Database with Dapper in C# and ASP.NET Core
- MySQL + Dapper - Create database if it doesn't exist on startup with C# and ASP.NET Core
- .NET 7.0 + Dapper + MySQL - CRUD API Tutorial in ASP.NET Core
- Postgres CRUD Operations in C# with Dapper Repository
- .NET 7.0 + C# - JWT Authentication Tutorial without ASP.NET Core Identity
- .NET 7.0 + Postgres - Connect to PostgreSQL Database with Dapper in C# and ASP.NET Core
- Postgres + Dapper - Create database if it doesn't exist on startup with C# and ASP.NET Core
- .NET 7.0 + Dapper + PostgreSQL - CRUD API Tutorial in ASP.NET Core
- SqlClient.SqlException - The certificate chain was issued by an authority that is not trusted
- .NET 7.0 + Dapper - Connect to MS SQL Server Database in ASP.NET Core
- .NET 7.0 + Dapper + MS SQL Server - CRUD API Tutorial in ASP.NET Core
- Dapper + SQL Server - Create database if it doesn't exist on startup in ASP.NET Core
- .NET 7.0 + Dapper - Connect to SQLite Database in ASP.NET Core
- .NET 7.0 + Dapper + SQLite - CRUD API Tutorial in ASP.NET Core
- C# + .NET 7.0 - Serialize (Convert) Enum to String in API Response
- .NET 7.0 + Dapper - Create Database Tables on Startup in ASP.NET Core
- C# + RestSharp - Add Bearer Token Authorization Header to HTTP Request in .NET
- C# + RestSharp - HTTP PUT Request Examples in .NET
- C# + RestSharp - HTTP DELETE Request Examples in .NET
- C# + RestSharp - HTTP GET Request Examples in .NET
- C# + RestSharp - POST a JSON Object to an API in .NET
- C# + RestSharp - HTTP POST Request Examples in .NET
- .NET 7.0 + RestSharp - Deserialize Dynamic JSON Response from HTTP Request
- .NET 7.0 - Create a Base Controller in .NET
- .NET 7.0 Auth - Sign & Validate JWT Without Core Identity
- .NET 7.0 - Create Custom AuthorizeAttribute and AllowAnonymous Attribute
- .NET 7.0 - Facebook Authentication API Tutorial with Example
- .NET 6.0 - Apply Authorize Attribute to All Controllers
- .NET 6.0 - Connect to InMemory Database with Entity Framework Core
- .NET 6.0 - Connect to SQLite Database with Entity Framework Core
- .NET 6.0 - Connect to PostgreSQL Database with Entity Framework Core
- .NET 6.0 - Connect to MySQL Database with Entity Framework Core
- .NET 6.0 - Connect to SQL Server with Entity Framework Core
- .NET 6.0 - CRUD API Example and Tutorial
- .NET 6.0 - Send an Email via SMTP with MailKit
- .NET 6.0 - Boilerplate API Tutorial with Email Sign Up, Verification, Authentication & Forgot Password
- .NET 6.0 - Role Based Authorization Tutorial with Example API
- .NET 6.0 - Minimal API Tutorial and Example
- .NET 6.0 - Execute EF Database Migrations from Code on Startup
- .NET 6.0 - Database Migrations to Different DB Per Environment (SQLite in Dev, SQL Server in Prod)
- .NET 6.0 - JWT Authentication with Refresh Tokens Tutorial with Example API
- .NET 6.0 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- .NET 6.0 - Global Error Handler Tutorial with Example
- .NET 6.0 - Hash and Verify Passwords with BCrypt
- .NET 6.0 - User Registration and Login Tutorial with Example API
- .NET 6.0 - Basic Authentication Tutorial with Example API
- .NET 6.0 - JWT Authentication Tutorial with Example API
- .NET 5.0 - Connect to MySQL Database with Entity Framework Core
- .NET 5.0 - Connect to SQL Server with Entity Framework Core
- .NET - Return Enum as String from API
- .NET - Startup Class in a Nutshell
- .NET - Program Class and Main Method in a Nutshell
- .NET + MSBuild - C# Project File (.csproj) in a Nutshell
- .NET 5.0 - CRUD API Example and Tutorial
- .NET 5.0 - Send an Email via SMTP with MailKit
- .NET 5.0 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password
- .NET 5.0 - Role Based Authorization Tutorial with Example API
- .NET 5.0 - Bare Bones API Tutorial
- VS Code + .NET - Debug a .NET Web App in Visual Studio Code
- .NET 5.0 API - JWT Authentication with Refresh Tokens
- .NET 5.0 - Automatic Entity Framework Migrations to SQL Database on Startup
- .NET 5.0 - Entity Framework Migrations for Multiple Databases (SQLite and SQL Server)
- .NET 5.0 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- .NET 5.0 - Global Error Handler Tutorial
- .NET 5.0 - Hash and Verify Passwords with BCrypt
- .NET 5.0 API - Allow CORS requests from any origin and with credentials
- .NET 5.0 - Simple API for Authentication, Registration and User Management
- .NET 5.0 - Basic Authentication Tutorial with Example API
- .NET 5.0 - JWT Authentication Tutorial with Example API
- .NET Core C# + AWS SES - Send Email via SMTP with AWS Simple Email Service
- Blazor WebAssembly - Fake Backend Example for Backendless Development
- Blazor WebAssembly - User Registration and Login Example & Tutorial
- ASP.NET Core 3.1 - Global Error Handler Tutorial
- Blazor WebAssembly - Authentication Without Identity
- Blazor WebAssembly - HTTP GET Request Examples
- Blazor WebAssembly - HTTP POST Request Examples
- Blazor WebAssembly - Display a list of items
- C# - Encode and Decode Base64 Strings
- Blazor WebAssembly - Basic HTTP Authentication Tutorial & Example
- Blazor WebAssembly - JWT Authentication Example & Tutorial
- Blazor WebAssembly - Get Query String Parameters with Navigation Manager
- Blazor WebAssembly - Form Validation Example
- ASP.NET Core Blazor WebAssembly - Communication Between Components
- ASP.NET Core 3.1 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- ASP.NET Core 3.1 - Hash and Verify Passwords with BCrypt
- ASP.NET Core 3.1 - Send Emails via SMTP with MailKit
- ASP.NET Core 3.1 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password
- ASP.NET Core - Setup Development Environment
- ASP.NET Core 3.1 API - JWT Authentication with Refresh Tokens
- ASP.NET Core API - Allow CORS requests from any origin and with credentials
- ASP.NET Core - EF Core Migrations for Multiple Databases (SQLite and SQL Server)
- ASP.NET Core - Automatic EF Core Migrations to SQL Database on Startup
- ASP.NET Core 3.1 - Basic Authentication Tutorial with Example API
- ASP.NET Core 3.1 - Role Based Authorization Tutorial with Example API
- ASP.NET Core 3.1 - Simple API for Authentication, Registration and User Management
- ASP.NET Core 3.1 - JWT Authentication Tutorial with Example API
- ASP.NET Core 2.2 - Role Based Authorization Tutorial with Example API
- C# - Pure Pagination Logic in C# / ASP.NET
- ASP.NET Core Razor Pages - Pagination Example
- ASP.NET Core 2.2 - Basic Authentication Tutorial with Example API
- ASP.NET Core 2.2 - JWT Authentication Tutorial with Example API
- ASP.NET Core 2.2 - Simple API for Authentication, Registration and User Management
- C# / ASP.NET - Domain Validation Logic in Domain Driven Design (DDD)
- ASP.NET MVC - Pagination Example with Logic like Google
- Fluent NHibernate - Unproxy Entity Objects with AutoMapper
- C# - Incremental Delay to Prevent Brute Force or Dictionary Attack
- Dynamic LINQ - Using strings to sort by properties and child object properties
- Web API 2 + ELMAH - Log ALL Unhandled Exceptions
- Moq - Get Setup() to return a dynamic collection from a fake repository
- Post a simple string value from AngularJS to .NET Web API
- ASP.NET Web API 2 - Enum Authorize Attribute
- ASP.NET MVC - Required Checkbox with Data Annotations
- Using MVC 4 Web Api with jQuery DataTables
- MVC CheckboxList for property of type IList<Enum>
- MVC3 redirect to mobile site and stop executing
- ASP.NET MVC3 + Altairis Web Security Toolkit
- NHibernate - Map Umbraco member profile properties with Custom Interceptor
- Populate ASP.NET dropdown list with month names using LINQ