using AsbCloudApp.Services; using System.Net.Http; using AsbCloudApp.Data; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System; namespace AsbCloudInfrastructure.Services { public class TimeZoneService : ITimeZoneService { private class TimeZoneInfo { public string Sunrise { get; set; } public double Lng { get; set; } public double Lat { get; set; } public string CountryCode { get; set; } public double GmtOffset { get; set; } public double RawOffset { get; set; } public string Sunset { get; set; } public string TimezoneId { get; set; } public double DstOffset { get; set; } public string CountryName { get; set; } public string Time { get; set; } } private const string timeZoneApiUrl = "http://api.geonames.org/timezoneJSON"; private const string timezoneApiUserName = "asbautodrilling"; public async Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token) { var lat = latitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var lng = longitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var url = $"{timeZoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}"; using var client = new HttpClient(); var response = await client.GetAsync(url, token) .ConfigureAwait(false); var responseJson = await response.Content.ReadAsStringAsync(token) .ConfigureAwait(false); if (!(responseJson.Contains("timezoneId") && responseJson.Contains("dstOffset"))) return null; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var timeZoneInfo = JsonSerializer.Deserialize(responseJson, options); return new TelemetryTimeZoneDto { Hours = timeZoneInfo.DstOffset, IsOverride = false, TimeZoneId = timeZoneInfo.TimezoneId, }; } public DateTime DateToUtc(DateTime date, double remoteTimezoneOffsetHours) { if (date == default) return new DateTime(0, DateTimeKind.Utc); var newDate = date.Kind switch { DateTimeKind.Local => date.ToUniversalTime(), DateTimeKind.Unspecified => date.AddHours(-remoteTimezoneOffsetHours), _ => date, }; return DateTime.SpecifyKind(newDate, DateTimeKind.Utc); } public DateTime DateToTimeZone(DateTime date, double remoteTimezoneOffsetHours) { if (date == default) return new DateTime(0, DateTimeKind.Unspecified); var newDate = date.Kind switch { DateTimeKind.Local => date.ToUniversalTime().AddHours(remoteTimezoneOffsetHours), DateTimeKind.Utc => date.AddHours(remoteTimezoneOffsetHours), _ => date, }; return DateTime.SpecifyKind(newDate, DateTimeKind.Unspecified); } } }