根据坐标获取当地时间

时间:2015-11-10 21:02:56

标签: c# datetime

我正在编写一个应用程序,该应用程序应根据您提供的坐标(lat& long)给出本地时间。

我只知道有两种方法可以做到:

1st:获取TimeZone名称,然后找到当地时间。 第二:使用Google API并将时间作为偏移量,UTC而不是本地时间。

我决定使用第一种方法因为看起来更容易,所以我决定使用GeoTimeZone来获得时区......问题是那时我不知道如何在TimeZone上获得当地时间......这是我为获取TimeZone名称而编写的代码。

string tz = TimeZoneLookup.GetTimeZone(lat, lon).Result;

变量lat& lon当然是坐标。

谢谢!

编辑:我的问题是如何在TimeZone上获取LocalTime?

6 个答案:

答案 0 :(得分:4)

您可以使用Google API来识别当前时区 .Net Fiddle example

public class Program
{
    public static 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);
    }

    public static void Main()
    {
        var myDateTime = GetLocalDateTime(33.8323, -117.8803, DateTime.UtcNow);
        Console.WriteLine(myDateTime.ToString());
    }
}

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; }
}

public static class ExtensionMethods 
{
    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);
    }
}

然后您可以轻松使用上面示例中显示的GetLocalDateTime(double latitude, double longitude, DateTime utcDate)方法:

public static void Main()
{
    var myDateTime = GetLocalDateTime(33.8323, -117.8803, DateTime.UtcNow);
    Console.WriteLine(myDateTime.ToString());
}

答案 1 :(得分:2)

这是我的解决方案。它可以离线运行(因此无需调用api)。它的速度很快,并且这些软件包在Nuget上得到了广泛的使用和提供。

var tzIana = TimeZoneLookup.GetTimeZone(lat, lng).Result;
var tzMs = TZConvert.IanaToWindows(tzIana);
var tzInfo = TimeZoneInfo.FindSystemTimeZoneById(tzMs);
var convertedTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzInfo);

答案 2 :(得分:1)

最后这就是我修复它的方法,我需要使用TimeZoneDb涂层将IANA TimeZone转换为Microsoft格式,所以这是代码:

string tz1 = TimeZoneLookup.GetTimeZone(lat, lon).Result;

                var timeZoneDbUseCases = new TimeZoneDbUseCases();
                var allTimeZones = timeZoneDbUseCases.GetAllTimeZones();
                var timeZone = timeZoneDbUseCases.GetTimeZoneWithIanaId(tz1);

                var timeZone1 = TimeZoneInfo.FindSystemTimeZoneById(timeZone.MicrosoftId);
                var localTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, timeZone1);

感谢所有帮助过的人,这些解决方案对我帮助很大,也许没有它们我无法实现它。

非常感谢!!

答案 3 :(得分:0)

您可以使用以下代码将当前UTC时间转换为本地时间:

var tz = "Eastern Standard Time"; // local time zone
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(tz);
var localTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, timeZone);

//Console.WriteLine(localTime.ToString("G"));
//Console.ReadLine();

答案 4 :(得分:0)

这里我的解决方案基于混合解决方案。需要RestSharp和NodaTime(均来自nuget)

    private static string WindowsToIana(string windowsZoneId)
    {
        if (windowsZoneId.Equals("UTC", StringComparison.Ordinal))
            return "Etc/UTC";

        var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;
        var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsZoneId);
        if (tzi == null) return null;
        var tzid = tzdbSource.MapTimeZoneId(tzi);
        if (tzid == null) return null;
        return tzdbSource.CanonicalIdMap[tzid];
    }

    private static string IanaToWindows(string ianaZoneId)
    {
        var utcZones = new[] { "Etc/UTC", "Etc/UCT", "Etc/GMT" };
        if (utcZones.Contains(ianaZoneId, StringComparer.Ordinal))
            return "UTC";

        var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;

        // resolve any link, since the CLDR doesn't necessarily use canonical IDs
        var links = tzdbSource.CanonicalIdMap
            .Where(x => x.Value.Equals(ianaZoneId, StringComparison.Ordinal))
            .Select(x => x.Key);

        // resolve canonical zones, and include original zone as well
        var possibleZones = tzdbSource.CanonicalIdMap.ContainsKey(ianaZoneId)
            ? links.Concat(new[] { tzdbSource.CanonicalIdMap[ianaZoneId], ianaZoneId })
            : links;

        // map the windows zone
        var mappings = tzdbSource.WindowsMapping.MapZones;
        var item = mappings.FirstOrDefault(x => x.TzdbIds.Any(possibleZones.Contains));
        if (item == null) return null;
        return item.WindowsId;
    }

    private static string GetIanaTimeZone(double latitude, double longitude, DateTime date)
    {
        RestClient client;
        string location;
        RestRequest request;
        RestResponse response;
        TimeSpan time_since_midnight_1970;
        double time_stamp;
        string time_zone = "";

        try
        {
            const string GOOGLE_API = "https://maps.googleapis.com";
            const string GOOGLE_TIMEZONE_REQUEST = "maps/api/timezone/xml";


            client = new RestClient(GOOGLE_API);
            request = new RestRequest(GOOGLE_TIMEZONE_REQUEST,
                                        Method.GET);
            location = String.Format("{0},{1}",
                                       latitude.ToString(CultureInfo.InvariantCulture),
                                       longitude.ToString(CultureInfo.InvariantCulture));

            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            time_since_midnight_1970 = date - origin;
            time_stamp = Math.Floor(time_since_midnight_1970.TotalSeconds);

            request.AddParameter("location", location);
            request.AddParameter("timestamp", time_stamp);
            request.AddParameter("sensor", "false");
            //request.AddParameter("key", yourgooglekey);

            response = (RestResponse)client.Execute(request);
            if (response.StatusDescription.Equals("OK"))
            {
                XmlNode node;
                XmlDocument xml_document = new XmlDocument();

                xml_document.LoadXml(response.Content);
                node = xml_document.SelectSingleNode(
                            "/TimeZoneResponse/time_zone_id");
                if (node != null)
                {
                    time_zone = node.InnerText;
                }
                else
                {

                }
            }
            else
            {

            }
        }
        catch (Exception ex)
        {

        }

        return time_zone;
    }

    public static DateTime? GetDateTimeFromCoordinates(DateTime? utc, double? latitude, double? longitude)
    {
        if (utc == null || latitude == null || longitude == null)
            return null;

        try
        {
            string iana_timezone = GetIanaTimeZone((double)latitude, (double)longitude, (DateTime)utc);
            if (string.IsNullOrWhiteSpace(iana_timezone))
                return null;

            string time_zone = IanaToWindows(iana_timezone);
            TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(time_zone);
            DateTime date = TimeZoneInfo.ConvertTimeFromUtc((DateTime)utc, tz);
            return date;
        }
        catch (Exception ex)
        {

            return null;
        }

    }
}

static void Main(string[] args)
{
    double latitude = -11.2026920;
    double longitude = 17.8738870;
    DateTime uct = DateTime.UtcNow;

   DateTime? ret = GetDateTimeFromCoordinates(utc,latitude,longitude);

}

答案 5 :(得分:0)

function jsonpRequest(url, data)
{
    let params = "";
    for (let key in data)
    {
        if (data.hasOwnProperty(key))
        {
            if (params.length == 0)
            {
                params += "?";
            }
            else
            {
                params += "&";
            }
            let encodedKey = encodeURIComponent(key);
            let encodedValue = encodeURIComponent(data[key]);
            params += encodedKey + "=" + encodedValue;
         }
    }
    let script = document.createElement('script');
    script.src = url + params;
    document.body.appendChild(script);
}

function getLocation() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    x.innerHTML = "Geolocation is not supported by this browser.";
  }
}
let lat_ini=[]; let lon_ini=[];
function showPosition(position) {
  lat_ini= position.coords.latitude;
  lon_ini= position.coords.longitude;
}
////delay time between lines
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
///////
function getGMT()
{
  getfinalGMT()
  getLocation()
  async function sample() {
    await sleep(2000);
let lat_str=lat_ini.toString();
let lng_str=" "+lon_ini.toString();

  let url = "https://api.opencagedata.com/geocode/v1/json";
  let data = {
    callback: "displayGMT",
    q: lat_str + lng_str,
    key: "fac4471073a347019196c1291e6a97d7"
  }
  jsonpRequest(url, data)
}
 sample();
 }
let your_GMT=[];
function displayGMT(data)
{
your_GMT=(Number(data.results[0].annotations.timezone.offset_string))
console.log(your_GMT)
}
/////
function getfinalGMT()
{
let lat=document.getElementById("lat_id").value; let lng=document.getElementById("lng_id").value;
let lat_str=lat.toString();
let lng_str=" "+lng.toString();

  let url = "https://api.opencagedata.com/geocode/v1/json";
  let data = {
    callback: "displayfinalGMT",
    q: lat + lng_str,
    key: "fac4471073a347019196c1291e6a97d7"
  }
  jsonpRequest(url, data)
 }
let final_GMT=[];
function displayfinalGMT(data)
{
final_GMT=(Number(data.results[0].annotations.timezone.offset_string))
console.log(final_GMT)
}
/////clock


const hourHand = document.querySelector('[data-hour-hand]')
const minuteHand = document.querySelector('[data-minute-hand]')
const secondHand = document.querySelector('[data-second-hand]')
  let dif_overall=[];
function setClock() {
   let gmt_diff=Number(your_GMT-final_GMT)/100
   if (gmt_diff>12){
      dif_overall=gmt_diff-12
   }
   else{
     dif_overall=gmt_diff
   }
    console.log(dif_overall)
  const currentDate = new Date()
  const secondsRatio = currentDate.getSeconds() / 60
  const minutesRatio = (secondsRatio + currentDate.getMinutes()) / 60
  const hoursRatio = (minutesRatio + currentDate.getHours() - dif_overall ) / 12
  setRotation(secondHand, secondsRatio)
  setRotation(minuteHand, minutesRatio)
  setRotation(hourHand, hoursRatio)
}

function setRotation(element, rotationRatio) {
  element.style.setProperty('--rotation', rotationRatio * 360)
}
function activate_clock(){
setClock()
setInterval(setClock, 1000)
}
*, *::after, *::before {
  box-sizing: border-box;
}

body {
  background: linear-gradient(to right, hsl(200, 100%, 50%), hsl(175, 100%, 50%));
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  overflow: hidden;
}

.clock {
  width: 200px;
  height: 200px;
  background-color: rgba(255, 255, 255, .8);
  border-radius: 50%;
  border: 2px solid black;
  position: relative;
}

.clock .number {
  --rotation: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  text-align: center;
  transform: rotate(var(--rotation));
  font-size: 1.5rem;
}

.clock .number1 { --rotation: 30deg; }
.clock .number2 { --rotation: 60deg; }
.clock .number3 { --rotation: 90deg; }
.clock .number4 { --rotation: 120deg; }
.clock .number5 { --rotation: 150deg; }
.clock .number6 { --rotation: 180deg; }
.clock .number7 { --rotation: 210deg; }
.clock .number8 { --rotation: 240deg; }
.clock .number9 { --rotation: 270deg; }
.clock .number10 { --rotation: 300deg; }
.clock .number11 { --rotation: 330deg; }

.clock .hand {
  --rotation: 0;
  position: absolute;
  bottom: 50%;
  left: 50%;
  border: 1px solid white;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  transform-origin: bottom;
  z-index: 10;
  transform: translateX(-50%) rotate(calc(var(--rotation) * 1deg));
}

.clock::after {
  content: '';
  position: absolute;
  background-color: black;
  z-index: 11;
  width: 15px;
  height: 15px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}

.clock .hand.second {
  width: 3px;
  height: 45%;
  background-color: red;
}

.clock .hand.minute {
  width: 7px;
  height: 40%;
  background-color: black;
}

.clock .hand.hour {
  width: 10px;
  height: 35%;
  background-color: black;
}














/* Background Styles Only */

@import url('https://fonts.googleapis.com/css?family=Raleway');

* {
    font-family: Raleway;
}

.side-links {
  position: absolute;
  top: 15px;
  right: 15px;
}

.side-link {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  margin-bottom: 10px;
  color: white;
  width: 180px;
  padding: 10px 0;
  border-radius: 10px;
}

.side-link-youtube {
  background-color: red;
}

.side-link-twitter {
  background-color: #1DA1F2;
}

.side-link-github {
  background-color: #6e5494;
}

.side-link-text {
  margin-left: 10px;
  font-size: 18px;
}

.side-link-icon {
  color: white;
  font-size: 30px;
}
<input type="text" id="lat_id" placeholder="lat"><br><br>
  <input type="text" id="lng_id" placeholder="lng"><br><br>
<button class="text" onClick="getLocation()">Location</button>
<button class="text" onClick="getGMT()"> GMT</button>
<button class="text" onClick="activate_clock()"> Activate</button>
<div class="clock">
  <div class="hand hour" data-hour-hand></div>
  <div class="hand minute" data-minute-hand></div>
  <div class="hand second" data-second-hand></div>
  <div class="number number1">1</div>
  <div class="number number2">2</div>
  <div class="number number3">3</div>
  <div class="number number4">4</div>
  <div class="number number5">5</div>
  <div class="number number6">6</div>
  <div class="number number7">7</div>
  <div class="number number8">8</div>
  <div class="number number9">9</div>
  <div class="number number10">10</div>
  <div class="number number11">11</div>
  <div class="number number12">12</div>
</div>