C# 根据坐标获取本地时间

C# 根据坐标获取本地时间,c#,datetime,C#,Datetime,我正在编写一个应用程序,它应该根据您给定的坐标(lat&long)给出本地时间 我只知道两种方法: 第一:获取时区名称,然后查找其本地时间。 第二:使用谷歌API,将时间作为偏移量接收,UTC不是本地时间 我决定使用第1种方法,因为它看起来更简单,所以我决定使用地理时区来获取时区。。。问题是我不知道如何获取该时区的当地时间。。。这是我用来获取时区名称的代码 string tz = TimeZoneLookup.GetTimeZone(lat, lon).Result; 变量lat和lon当然是

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

我只知道两种方法:

第一:获取时区名称,然后查找其本地时间。 第二:使用谷歌API,将时间作为偏移量接收,UTC不是本地时间

我决定使用第1种方法,因为它看起来更简单,所以我决定使用地理时区来获取时区。。。问题是我不知道如何获取该时区的当地时间。。。这是我用来获取时区名称的代码

string tz = TimeZoneLookup.GetTimeZone(lat, lon).Result;
变量
lat
lon
当然是坐标

谢谢大家!


编辑:我的问题是如何获取该时区的本地时间?

您可以使用以下代码将当前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();

您可以使用Google api识别当前时区。
:


最后,这是我修复它的方式,我需要使用TimeZoneDb livery,它将IANA时区转换为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);
感谢所有帮助过我的人,这两种解决方案对我都有很大帮助,如果没有它们,我可能无法实现


非常感谢

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


这是我的解决办法。它可以脱机工作(因此不需要调用api)。它的速度很快,并且包在Nuget上被广泛使用和提供

string tzIana = TimeZoneLookup.GetTimeZone(lat, lng).Result;
TimeZoneInfo tzInfo = TZConvert.GetTimeZoneInfo(tzIana);
DateTimeOffset convertedTime = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzInfo);
函数jsonpRequest(url、数据)
{
设params=“”;
for(让我们输入数据)
{
if(data.hasOwnProperty(key))
{
如果(params.length==0)
{
参数+=“?”;
}
其他的
{
参数+=“&”;
}
设encodedKey=encodeURIComponent(键);
让encodedValue=encodeURIComponent(数据[key]);
参数+=encodedKey+“=”+encodedValue;
}
}
让script=document.createElement('script');
script.src=url+params;
document.body.appendChild(脚本);
}
函数getLocation(){
if(导航器.地理位置){
navigator.geolocation.getCurrentPosition(showPosition);
}否则{
x、 innerHTML=“此浏览器不支持地理位置。”;
}
}
让lat_ini=[];让lon_ini=[];
功能显示位置(位置){
纬度ini=位置坐标纬度;
lon_ini=位置坐标经度;
}
////线间延迟时间
功能睡眠(ms){
返回新承诺(resolve=>setTimeout(resolve,ms));
}
///////
函数getGMT()
{
getfinalGMT()
getLocation()
异步函数示例(){
等待睡眠(2000年);
设lat_str=lat_ini.toString();
让lng_str=“”+lon_ini.toString();
让url=”https://api.opencagedata.com/geocode/v1/json";
让数据={
回调:“displayGMT”,
问:拉图街+液化天然气街,
键:“fac4471073a347019196c1291e6a97d7”
}
jsonpRequest(url、数据)
}
样本();
}
让您的_GMT=[];
函数显示GMT(数据)
{
您的\u GMT=(数字(data.results[0].annotations.timezone.offset\u字符串))
console.log(您的\u GMT)
}
/////
函数getfinalGMT()
{
设lat=document.getElementById(“lat_id”).value;设lng=document.getElementById(“lng_id”).value;
设lat_str=lat.toString();
让lng_str=“”+lng.toString();
让url=”https://api.opencagedata.com/geocode/v1/json";
让数据={
回调:“displayfinalGMT”,
q:lat+lng_街,
键:“fac4471073a347019196c1291e6a97d7”
}
jsonpRequest(url、数据)
}
让最后的格林尼治标准时间=[];
函数displayfinalGMT(数据)
{
final_GMT=(数字(data.results[0].annotations.timezone.offset_string))
console.log(最终格林尼治标准时间)
}
/////钟
const hourHand=document.querySelector(“[data hourHand]”)
const minuteHand=document.querySelector(“[data minuteHand]”)
const secondHand=document.querySelector(“[data secondHand]”)
让dif_总体=[];
函数setClock(){
让gmt\u diff=Number(您的\u gmt-final\u gmt)/100
如果(gmt_diff>12){
dif_总体=gmt_差异-12
}
否则{
dif_总体=gmt_差异
}
控制台日志(dif_总体)
const currentDate=新日期()
const secondsRatio=currentDate.getSeconds()/60
const minutesRatio=(secondsRatio+currentDate.getMinutes())/60
const hoursRatio=(分钟比率+currentDate.getHours()-dif_总体)/12
设置旋转(二手、二手)
设置旋转(分钟手、分钟比)
设置旋转(小时和小时比率)
}
函数设置旋转(元素、旋转比){
element.style.setProperty('--rotation',rotationRatio*360)
}
功能激活_时钟(){
设置时钟()
设置间隔(设置时钟,1000)
}
*,*::之后,*::之前{
框大小:边框框;
}
身体{
背景:线性梯度(向右,hsl(200,100%,50%),hsl(175,100%,50%);
显示器:flex;
证明内容:中心;
对齐项目:居中;
最小高度:100vh;
溢出:隐藏;
}
.钟{
宽度:200px;
高度:200px;
背景色:rgba(255、255、255、.8);
边界半径:50%;
边框:2件纯黑;
位置:相对位置;
}
.钟.号码{
--轮换:0;
位置:绝对位置;
宽度:100%;
身高:100%;
文本对齐:居中;
变换:旋转(var(--rotation));
字体大小:1.5rem;
}
.时钟编号1{--旋转:30度;}
.时钟编号2{--旋转:60度;}
.时钟编号3{--旋转:90度;}
.时钟编号4{--旋转:120度;}
.时钟编号5{--旋转:150度;}
.时钟编号6{--旋转:180度;}
.时钟编号7{--旋转:210度;}
.时钟编号8{--旋转:240度;}
.时钟编号9{--旋转:270度;}
.时钟编号10{--旋转:300度;}
.时钟编号11{--旋转:330度;}
.时钟.指针{
--轮换:0;
位置:绝对位置;
底部:50%;
左:50%;
边框:1px纯白;
边框左上半径:10px;
边框右上角半径:10px;
变换原点:底部;
z指数:10;
变换:translateX(-50%)旋转(计算(变量(-旋转)*1deg));
}
.钟::之后{
内容:'';
位置:绝对位置;
背景色:黑色;
z指数:
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);
    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);

}
string tzIana = TimeZoneLookup.GetTimeZone(lat, lng).Result;
TimeZoneInfo tzInfo = TZConvert.GetTimeZoneInfo(tzIana);
DateTimeOffset convertedTime = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzInfo);