我正在编写一个应用程序,该应用程序应根据您提供的坐标(lat& long)给出本地时间。
我只知道有两种方法可以做到:
1st:获取TimeZone名称,然后找到当地时间。 第二:使用Google API并将时间作为偏移量,UTC而不是本地时间。
我决定使用第一种方法因为看起来更容易,所以我决定使用GeoTimeZone来获得时区......问题是那时我不知道如何在TimeZone上获得当地时间......这是我为获取TimeZone名称而编写的代码。
string tz = TimeZoneLookup.GetTimeZone(lat, lon).Result;
变量lat
& lon
当然是坐标。
谢谢!
编辑:我的问题是如何在TimeZone上获取LocalTime?
答案 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>