给定一个位置的经度和纬度,如何知道该位置的有效时区?
在大多数情况下,我们正在寻找IANA/Olson时区id,尽管有些服务可能只返回UTC偏移量或其他一些时区标识符。详细信息请阅读时区标签信息。
给定一个位置的经度和纬度,如何知道该位置的有效时区?
在大多数情况下,我们正在寻找IANA/Olson时区id,尽管有些服务可能只返回UTC偏移量或其他一些时区标识符。详细信息请阅读时区标签信息。
当前回答
对于我们这些使用Javascript并希望通过谷歌api从邮政编码获取时区的人来说,这里有一个方法。
通过地理定位获取lat/lng 通过这个参数获取时区 进入时区API。 此处使用Luxon进行时区转换。
注意:我的理解是,邮政编码在不同的国家并不是唯一的,所以这可能最适合在美国使用。
const googleMapsClient; // instantiate your client here
const zipcode = '90210'
const myDateThatNeedsTZAdjustment; // define your date that needs adjusting
// fetch lat/lng from google api by zipcode
const geocodeResponse = await googleMapsClient.geocode({ address: zipcode }).asPromise();
if (geocodeResponse.json.status === 'OK') {
lat = geocodeResponse.json.results[0].geometry.location.lat;
lng = geocodeResponse.json.results[0].geometry.location.lng;
} else {
console.log('Geocode was not successful for the following reason: ' + status);
}
// prepare lat/lng and timestamp of profile created_at to fetch time zone
const location = `${lat},${lng}`;
const timestamp = new Date().valueOf() / 1000;
const timezoneResponse = await googleMapsClient
.timezone({ location: location, timestamp: timestamp })
.asPromise();
const timeZoneId = timezoneResponse.json.timeZoneId;
// adjust by setting timezone
const timezoneAdjustedDate = DateTime.fromJSDate(
myDateThatNeedsTZAdjustment
).setZone(timeZoneId);
其他回答
如果您想使用geonames.org,请使用这段代码。(但是geonames.org有时很慢)
String get_time_zone_time_geonames(GeoPoint gp){
String erg = "";
double Longitude = gp.getLongitudeE6()/1E6;
double Latitude = gp.getLatitudeE6()/1E6;
String request = "http://ws.geonames.org/timezone?lat="+Latitude+"&lng="+ Longitude+ "&style=full";
URL time_zone_time = null;
InputStream input;
// final StringBuilder sBuf = new StringBuilder();
try {
time_zone_time = new URL(request);
try {
input = time_zone_time.openConnection().getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
final StringBuilder sBuf = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sBuf.append(line);
}
} catch (IOException e) {
Log.e(e.getMessage(), "XML parser, stream2string 1");
} finally {
try {
input.close();
} catch (IOException e) {
Log.e(e.getMessage(), "XML parser, stream2string 2");
}
}
String xmltext = sBuf.toString();
int startpos = xmltext.indexOf("<geonames");
xmltext = xmltext.substring(startpos);
XmlPullParser parser;
try {
parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(new StringReader (xmltext));
int eventType = parser.getEventType();
String tagName = "";
while(eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) {
case XmlPullParser.START_TAG:
tagName = parser.getName();
break;
case XmlPullParser.TEXT :
if (tagName.equalsIgnoreCase("time"))
erg = parser.getText();
break;
}
try {
eventType = parser.next();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (XmlPullParserException e) {
e.printStackTrace();
erg += e.toString();
}
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
return erg;
}
并将其用于:
GeoPoint gp = new GeoPoint(39.6034810,-119.6822510);
String Current_TimeZone_Time = get_time_zone_time_geonames(gp);
好的,这是没有正确NTP时间的短版本:
String get_xml_server_reponse(String server_url){
URL xml_server = null;
String xmltext = "";
InputStream input;
try {
xml_server = new URL(server_url);
try {
input = xml_server.openConnection().getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
final StringBuilder sBuf = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null)
{
sBuf.append(line);
}
}
catch (IOException e)
{
Log.e(e.getMessage(), "XML parser, stream2string 1");
}
finally {
try {
input.close();
}
catch (IOException e)
{
Log.e(e.getMessage(), "XML parser, stream2string 2");
}
}
xmltext = sBuf.toString();
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
return xmltext;
}
long get_time_zone_time_l(GeoPoint gp){
String raw_offset = "";
String dst_offset = "";
double Longitude = gp.getLongitudeE6()/1E6;
double Latitude = gp.getLatitudeE6()/1E6;
long tsLong = System.currentTimeMillis()/1000;
if (tsLong != 0)
{
// https://maps.googleapis.com/maps/api/timezone/xml?location=39.6034810,-119.6822510×tamp=1331161200&sensor=false
String request = "https://maps.googleapis.com/maps/api/timezone/xml?location="+Latitude+","+ Longitude+ "×tamp="+tsLong +"&sensor=false";
String xmltext = get_xml_server_reponse(request);
if(xmltext.compareTo("")!= 0)
{
int startpos = xmltext.indexOf("<TimeZoneResponse");
xmltext = xmltext.substring(startpos);
XmlPullParser parser;
try {
parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(new StringReader (xmltext));
int eventType = parser.getEventType();
String tagName = "";
while(eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) {
case XmlPullParser.START_TAG:
tagName = parser.getName();
break;
case XmlPullParser.TEXT :
if (tagName.equalsIgnoreCase("raw_offset"))
if(raw_offset.compareTo("")== 0)
raw_offset = parser.getText();
if (tagName.equalsIgnoreCase("dst_offset"))
if(dst_offset.compareTo("")== 0)
dst_offset = parser.getText();
break;
}
try {
eventType = parser.next();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (XmlPullParserException e) {
e.printStackTrace();
erg += e.toString();
}
}
int ro = 0;
if(raw_offset.compareTo("")!= 0)
{
float rof = str_to_float(raw_offset);
ro = (int)rof;
}
int dof = 0;
if(dst_offset.compareTo("")!= 0)
{
float doff = str_to_float(dst_offset);
dof = (int)doff;
}
tsLong = (tsLong + ro + dof) * 1000;
}
return tsLong;
}
并将其用于:
GeoPoint gp = new GeoPoint(39.6034810,-119.6822510);
long Current_TimeZone_Time_l = get_time_zone_time_l(gp);
通过使用纬度和经度得到当前位置下面的时区代码为我工作
String data = null;
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location ll = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
double lat = 0,lng = 0;
if(ll!=null){
lat=ll.getLatitude();
lng=ll.getLongitude();
}
System.out.println(" Last known location of device == "+lat+" "+lng);
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
timezoneurl = timezoneurl+"location=22.7260783,75.8781553×tamp=1331161200";
// timezoneurl = timezoneurl+"location="+lat+","+lng+"×tamp=1331161200";
URL url = new URL(timezoneurl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
try {
iStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
urlConnection.disconnect();
}
try {
if(data!=null){
JSONObject jobj=new JSONObject(data);
timezoneId = jobj.getString("timeZoneId");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
format.setTimeZone(TimeZone.getTimeZone(timezoneId));
Calendar cl = Calendar.getInstance(TimeZone.getTimeZone(timezoneId));
System.out.println("time zone id in android == "+timezoneId);
System.out.println("time zone of device in android == "+TimeZone.getTimeZone(timezoneId));
System.out.println("time fo device in android "+cl.getTime());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
你可以使用geolocator.js轻松获得时区和更多…
它使用需要密钥的谷歌api。首先你配置geolocator
geolocator.config({
language: "en",
google: {
version: "3",
key: "YOUR-GOOGLE-API-KEY"
}
});
获取TimeZone,如果你有坐标:
geolocator.getTimeZone(options, function (err, timezone) {
console.log(err || timezone);
});
示例输出:
{
id: "Europe/Paris",
name: "Central European Standard Time",
abbr: "CEST",
dstOffset: 0,
rawOffset: 3600,
timestamp: 1455733120
}
定位,然后获得时区和更多
如果没有坐标,可以先定位用户位置。
下面的例子将首先尝试HTML5 Geolocation API来获取坐标。如果失败或被拒绝,它将通过Geo-IP查找获得坐标。最后,它将获得时区和更多…
var options = {
enableHighAccuracy: true,
timeout: 6000,
maximumAge: 0,
desiredAccuracy: 30,
fallbackToIP: true, // if HTML5 fails or rejected
addressLookup: true, // this will get full address information
timezone: true,
map: "my-map" // this will even create a map for you
};
geolocator.locate(options, function (err, location) {
console.log(err || location);
});
示例输出:
{
coords: {
latitude: 37.4224764,
longitude: -122.0842499,
accuracy: 30,
altitude: null,
altitudeAccuracy: null,
heading: null,
speed: null
},
address: {
commonName: "",
street: "Amphitheatre Pkwy",
route: "Amphitheatre Pkwy",
streetNumber: "1600",
neighborhood: "",
town: "",
city: "Mountain View",
region: "Santa Clara County",
state: "California",
stateCode: "CA",
postalCode: "94043",
country: "United States",
countryCode: "US"
},
formattedAddress: "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
type: "ROOFTOP",
placeId: "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
timezone: {
id: "America/Los_Angeles",
name: "Pacific Standard Time",
abbr: "PST",
dstOffset: 0,
rawOffset: -28800
},
flag: "//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/flags/4x3/us.svg",
map: {
element: HTMLElement,
instance: Object, // google.maps.Map
marker: Object, // google.maps.Marker
infoWindow: Object, // google.maps.InfoWindow
options: Object // map options
},
timestamp: 1456795956380
}
node.js的这个解决方案怎么样 https://github.com/mattbornski/tzwhere
和它的Python对等体: https://github.com/pegler/pytzwhere