ChatGPT解决这个技术问题 Extra ChatGPT

如何使用纬度和经度坐标从某个位置获取时区?

给定一个位置的纬度和经度,如何知道该位置的有效时区?

在大多数情况下,我们正在寻找 IANA/Olson 时区 ID,尽管某些服务可能只返回 UTC 偏移量或其他一些时区标识符。请阅读timezone tag info了解详情。

我注意到的一件事是在确定时区时没有任何 UTC 时间戳要求。例如,伦敦的长/纬度不足以确定时区是 GMT 或 BST(英国夏令时/夏令时)的天气。所以肯定要确定正确的时区,您需要 lat、long 和 UTC 时间戳。
@MichaelWaterfall - 要确定您是在 GMT (UTC+0000) 还是 BST (UTC+0100) - 是的,您是绝对正确的。但这些是时区偏移量,而不是时区标识符。两者都包含在 IANA 时区数据库的同一 "Europe/London" 时区标识符中。
啊,好吧,一旦使用给定的时区标识符渲染时间,就会添加夏令时偏移量(如果需要)?
它仍然可能需要 UTC 时间戳。例如,俄罗斯在过去 6 年中 4 次更改时区边界。 en.wikipedia.org/wiki/Time_in_Russia
@thur - 就边界本身而言,随着边界争端的开始或结束,每年都有一些历史差异。但是,当发生像 Arnial 所描述的那样的转变时,tzdb 会为受影响的区域创建一个新的时区,因此该区域的所有时间都会被计算在内 - 包括历史差异。我们称之为“区域分割”。一个很好的俄语示例是 Europe/Astrakhan,它使用 tzdb 2016b 从 Europe/Volgograd 中分离出来。

3
39 revs, 12 users 89%

时区定位网络服务

谷歌地图时区 API

必应地图时区 API

Azure 地图时区 API

GeoNames 时区 API

时区数据库 API

AskGeo - 商业(但可以说比 GeoNames 更准确)

GeoGarage Time Zone API - 商业,专注于航海时区。

原始时区边界数据

Timezone Boundary Builder - 从 OpenStreetMaps 地图数据构建时区 shapefile。包括海岸线附近的领海。

以下项目以前是时区边界数据的来源,但不再积极维护。

tz_world - 来自 Eric Muller 的原始 shapefile 数据

whereonearth-timezone - 合并了 WOEDB 数据的 GeoJSON 版本

时区地理位置离线实现

使用时区边界生成器数据的实现

node-geo-tz - JavaScript 库(仅限 Node.js)

时间空间 - JavaScript 库

tz-lookup-oss - JavaScript 库

GeoTimeZone - .NET 库

地理时区 - PHP 库

timezonefinder - Python 库

ZoneDetect - C 库

时间形状 - Java 库

TimeZoneMap - Java 和 Android 库

lutz - R 库

go-tz -Go 库

时区查找 - Go 库

docker-timezone-lookup - docker 容器包装 node-geo-tz

使用旧 tz_world 数据的实现

latlong - Go 库(也请阅读这篇文章。)

TimeZoneMapper - Java 库

tzwhere - JavaScript/节点库

pytzwhere - Python 库

timezone_finder - Ruby 库

LatLongToTimeZone - Java 和 Swift 库

现在几点了? - 描述 PHP 和 MongoDB 的博客文章

rundel/时区 - R 库

调用其中一种 Web 服务的库

timezone - 调用 GeoNames 的 Ruby gem

AskGeo 有自己的库,用于从 Java 或 .Net 调用

GeoNames 拥有几乎所有内容的客户端库

自托管网络服务

geo2tz - 基于时区查找,可通过 Docker 映像获得

其他想法

使用 R-Tree 查找最近的城市

使用 MySQL 查找最近的城市

如果您知道任何其他人,请更新此列表

另外,请注意,最近城市方法可能不会产生“正确”的结果,只是一个近似值。

转换为 Windows 区域

列出的大多数方法都将返回 IANA 时区 ID。如果您需要转换为 Windows 时区以与 .NET 中的 TimeZoneInfo 类一起使用,请使用 TimeZoneConverter 库。

不要使用 zone.tab

tz database 包含一个名为 zone.tab 的文件。该文件主要用于提供时区列表供用户选择。它包括每个时区的参考点的纬度和经度坐标。这允许创建突出这些点的地图。例如,请参阅 the moment-timezone home page 上显示的交互式地图。

虽然使用此数据从纬度和经度坐标解析时区可能很诱人,但请考虑这些是点而不是边界。最好的办法是确定最近的点,在许多情况下这不是正确的点。

考虑以下示例:

https://i.stack.imgur.com/tjd5u.png

两个方块代表不同的时区,其中每个方块中的黑点是参考位置,例如可以在 zone.tab 中找到的内容。蓝点代表我们试图为其查找时区的位置。显然,这个位置在左侧的橙色区域内,但如果我们只看离参考点最近的距离,它将解析为右侧的绿色区域。


GeoNames 实际上非常适合我的需要。谢谢!
@Matt但是,据我了解,目前没有离线数据库可以根据位置坐标提供时区信息和UTC偏移量?
@MattJohnson 我如何使用地名客户端库
这些新的 Google API 费率是敲诈勒索的。截至 7 月 18 日,以 1 美元的价格收到 200 个请求。这是 10 倍的增长。
@KanagaveluSugumar - 每个库的语言都包含在列表中。当前对 Java 的最高建议是 TimeShape
M
Matt Johnson-Pint

这个 node.js 的解决方案怎么样https://github.com/mattbornski/tzwhere

及其 Python 对应物:https://github.com/pegler/pytzwhere


我将这些添加到上面的社区 wiki 答案中。谢谢!
J
Joonathan

我们在 Teleport 刚刚开始 opening up our API's,其中一个用例还公开了坐标的 TZ 信息。

例如,可以通过以下方式请求我们所有可用的 TZ 坐标信息:

curl -s https://api.teleport.org/api/locations/59.4372,24.7453/?embed=location:nearest-cities/location:nearest-city/city:timezone/tz:offsets-now | jq '._embedded."location:nearest-cities"[0]._embedded."location:nearest-city"._embedded."city:timezone"'

这将返回以下内容

{
  "_embedded": {
    "tz:offsets-now": {
      "_links": {
        "self": {
          "href": "https://api.teleport.org/api/timezones/iana:Europe%2FTallinn/offsets/?date=2015-09-07T11%3A20%3A09Z"
        }
      },
      "base_offset_min": 120,
      "dst_offset_min": 60,
      "end_time": "2015-10-25T01:00:00Z",
      "short_name": "EEST",
      "total_offset_min": 180,
      "transition_time": "2015-03-29T01:00:00Z"
    }
  },
  "_links": {
    "self": {
      "href": "https://api.teleport.org/api/timezones/iana:Europe%2FTallinn/"
    },
    "tz:offsets": {
      "href": "https://api.teleport.org/api/timezones/iana:Europe%2FTallinn/offsets/{?date}",
      "templated": true
    },
    "tz:offsets-now": {
      "href": "https://api.teleport.org/api/timezones/iana:Europe%2FTallinn/offsets/?date=2015-09-07T11%3A20%3A09Z"
    }
  },
  "iana_name": "Europe/Tallinn"
}

对于我使用 ./jq 进行 JSON 解析的示例。


感谢分享。它是在做最近城市的方法,还是在使用多边形内的方法? (参见我上面两个正方形的图表。)
嗨 Joonathan,这是我第一次在 json 中看到像你这样的对象或数组名称,例如这个:“location:nearest-cities”:[我以后如何才能得到结果? $city = $data->_embedded->location:nearest->cities[0]->_links->location:nearest->cities->name 这是不允许的
S
Stiño

下面介绍如何使用 Google 的脚本编辑器在 gsheet 中获取 timezoneName 和 timeZoneId。

https://i.stack.imgur.com/ZXmrF.png

第 1 步。Get an API key 用于 Google 的时区 API

步骤 2. 创建一个新的 gsheet。在“工具”菜单下单击“脚本编辑器”。添加以下代码:

function getTimezone(lat, long) {  
  var apiKey = 'INSERTAPIKEYHERE'
  var url = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + lat + ',' + long + '&timestamp=1331161200&key=' + apiKey 
  var response = UrlFetchApp.fetch(url);
  var data = JSON.parse(response.getContentText());
  return data["timeZoneName"];
}

步骤 3. 保存并发布您的 getTimezone() 函数并如上图所示使用它。


O
Onur Yıldırım

您可以使用 geolocator.js 轻松获取时区等...

它使用需要密钥的 Google API。所以,首先你配置地理定位器:

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
}

找到然后获取 TimeZone 等

如果没有坐标,可以先定位用户位置。

下面的示例将首先尝试 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
}

C
Community

https://en.wikipedia.org/wiki/Great-circle_distance

这是使用 JSON 数据的一个很好的实现:https://github.com/agap/llttz

public TimeZone nearestTimeZone(Location node) {
    double bestDistance = Double.MAX_VALUE;
    Location bestGuess = timeZones.get(0);

    for (Location current : timeZones.subList(1, timeZones.size())) {
        double newDistance = distanceInKilometers(node, current);

        if (newDistance < bestDistance) {
            bestDistance = newDistance;
            bestGuess = current;
        }
    }

    return java.util.TimeZone.getTimeZone(bestGuess.getZone());
}

  protected double distanceInKilometers(final double latFrom, final double lonFrom, final double latTo, final double lonTo) {
        final double meridianLength = 111.1;
        return meridianLength * centralAngle(latFrom, lonFrom, latTo, lonTo);
    }

    protected double centralAngle(final Location from, final Location to) {
        return centralAngle(from.getLatitude(), from.getLongitude(), to.getLatitude(), to.getLongitude());
    }

    protected double centralAngle(final double latFrom, final double lonFrom, final double latTo, final double lonTo) {
        final double latFromRad = toRadians(latFrom),
                lonFromRad = toRadians(lonFrom),
                latToRad   = toRadians(latTo),
                lonToRad   = toRadians(lonTo);

        final double centralAngle = toDegrees(acos(sin(latFromRad) * sin(latToRad) + cos(latFromRad) * cos(latToRad) * cos(lonToRad - lonFromRad)));

        return centralAngle <= 180.0 ? centralAngle : (360.0 - centralAngle);
    }

    protected double distanceInKilometers(final Location from, final Location to) {
        return distanceInKilometers(from.getLatitude(), from.getLongitude(), to.getLatitude(), to.getLongitude());
    }
}

您还可以从链接中添加一些内容吗?
l
legel

认识到这是一个比大多数人想象的更复杂的问题确实很重要。在实践中,我们中的许多人也愿意接受一套适用于“尽可能多的情况”的工作代码,其中至少可以识别出致命问题并将其最小化。因此,我将所有这些内容和 OP 的精神牢记在心。最后,对于那些试图将 GPS 转换为时区并最终目标是拥有一个对位置敏感的时间对象(更重要的是帮助提高来自本 wiki 的时间对象的平均实现的质量)的其他人的实用价值,这里是我在 Python 中生成的内容(请随意编辑):

import pytz
from datetime import datetime
from tzwhere import tzwhere

def timezoned_unixtime(latitude, longitude, dt):
    tzw = tzwhere.tzwhere()
    timezone_str = tzw.tzNameAt(latitude, longitude)
    timezone = pytz.timezone(timezone_str)
    timezone_aware_datetime = timezone.localize(dt, is_dst=None)
    unix_time = (timezone_aware_datetime - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
    return unix_time

dt = datetime(year=2017, month=1, day=17, hour=12, minute=0, second=0)
print timezoned_unixtime(latitude=40.747854, longitude=-74.004733, dt=dt)

谢谢,但这看起来像是一些使用 pytzwhere 的代码,该代码已在主要社区 wiki 答案中列出。如果您打算提供如何将 pytzwhere 与 pytz 结合使用的示例,您可能希望将其作为 PR 提交给 pytzwhere 项目本身。在这里,我们只是在寻找 lat/lon 到 tz 的解决方案——其中 pytzwhere 就是其中之一。
b
buræquete

网上有几个来源包含时区的 geojson 数据(这是一个,这是另一个) 使用几何库从 geojson 坐标创建多边形对象(shapely [python]、GEOS [c++]、JTS [java]、NTS [.net ])。将您的 lat/lng 转换为点对象(但是您的库表示该对象)并检查它是否与时区多边形相交。 from shapely.geometry import Polygon, Point def get_tz_from_lat_lng(lat, lng): for tz, geojson in timezones.iteritems(): coordinates = geojson['features'][0]['geometry']['coordinates'] 多边形 = Polygon(coordinates) point = Point(lng, lat) if polygon.contains(point): return tz


T
Tobias Gassmann

披露:我是下面描述的 docker-image 的作者

我已将 https://github.com/evansiroky/node-geo-tz 包装在一个非常简单的 docker-container 中

https://hub.docker.com/repository/docker/tobias74/timezone-lookup

您可以使用以下命令启动 docker-container

docker run -p 80:3000 tobias74/timezone-lookup:latest

这会在端口 3000 上公开本地主机上的查找服务。然后您可以通过以下方式进行时区查找

curl "localhost:3000/timezone?latitude=12&longitude=34"

I
Ingo

尝试此代码以使用 Java 中的 Google Time Zone API 与当前 NTP 时间客户端并正确 UTC_Datetime_from_timestamp 转换:

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;

  }     


 private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

 class NTP_UTC_Time
 {
     private static final String TAG = "SntpClient";

     private static final int RECEIVE_TIME_OFFSET = 32;
     private static final int TRANSMIT_TIME_OFFSET = 40;
     private static final int NTP_PACKET_SIZE = 48;

     private static final int NTP_PORT = 123;
     private static final int NTP_MODE_CLIENT = 3;
     private static final int NTP_VERSION = 3;

     // Number of seconds between Jan 1, 1900 and Jan 1, 1970
     // 70 years plus 17 leap days
     private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

     private long mNtpTime;

     public boolean requestTime(String host, int timeout) {
         try {
             DatagramSocket socket = new DatagramSocket();
             socket.setSoTimeout(timeout);
             InetAddress address = InetAddress.getByName(host);
             byte[] buffer = new byte[NTP_PACKET_SIZE];
             DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

             buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

             writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

             socket.send(request);

             // read the response
             DatagramPacket response = new DatagramPacket(buffer, buffer.length);
             socket.receive(response);          
             socket.close();

             mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);            
         } catch (Exception e) {
           //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
             return false;
         }

         return true;
     }


     public long getNtpTime() {
         return mNtpTime;
     }


     /**
      * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
      */
     private long read32(byte[] buffer, int offset) {
         byte b0 = buffer[offset];
         byte b1 = buffer[offset+1];
         byte b2 = buffer[offset+2];
         byte b3 = buffer[offset+3];

         // convert signed bytes to unsigned values
         int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
         int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
         int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
         int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

         return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
     }

     /**
      * Reads the NTP time stamp at the given offset in the buffer and returns 
      * it as a system time (milliseconds since January 1, 1970).
      */    
     private long readTimeStamp(byte[] buffer, int offset) {
         long seconds = read32(buffer, offset);
         long fraction = read32(buffer, offset + 4);
         return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);        
     }

     /**
      * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
      */    
     private void writeTimeStamp(byte[] buffer, int offset) {        
         int ofs =  offset++;

         for (int i=ofs;i<(ofs+8);i++)
           buffer[i] = (byte)(0);             
     }

 }

 String get_time_zone_time(GeoPoint gp){

        String erg = "";
        String raw_offset = "";
        String dst_offset = "";

        double Longitude = gp.getLongitudeE6()/1E6;
        double Latitude = gp.getLatitudeE6()/1E6;



        long tsLong = 0; // System.currentTimeMillis()/1000;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          tsLong = client.getNtpTime();
        }

        if (tsLong != 0)
        {

        tsLong = tsLong  / 1000;

        // https://maps.googleapis.com/maps/api/timezone/xml?location=39.6034810,-119.6822510&timestamp=1331161200&sensor=false

        String request = "https://maps.googleapis.com/maps/api/timezone/xml?location="+Latitude+","+ Longitude+ "&timestamp="+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;



        erg = get_UTC_Datetime_from_timestamp(tsLong);
        }


  return erg;

}

并将其用于:

GeoPoint gp = new GeoPoint(39.6034810,-119.6822510);
String Current_TimeZone_Time = get_time_zone_time(gp);

这似乎是一个简单任务的大量代码。您在那里有一个完整的 NTP 客户端,这可能是个好主意 - 但不一定是必需的。请问可以瘦一点吗?
I
Ingo

好的,这是没有正确 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&timestamp=1331161200&sensor=false

        String request = "https://maps.googleapis.com/maps/api/timezone/xml?location="+Latitude+","+ Longitude+ "&timestamp="+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);

I
Ingo

如果您想使用 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);

U
Unheilig

来自古比:

import geocoders
g = geocoders.GoogleV3()
place, (lat, lng) = g.geocode('Fairbanks')
print place, (lat, lng)
Fairbanks, AK, USA (64.8377778, -147.7163889)
timezone = g.timezone((lat, lng))
print timezone.dst

DstTzInfo 的绑定方法 America/Anchorage.dst

美国/安克雷奇 LMT-1 天,标准时间 14:00:00


我认为Guppy是一个错字。你的意思是 Geopy 还是别的什么?
A
Arnold Brown

通过使用纬度和经度获取以下代码为我工作的当前位置的时区

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&timestamp=1331161200";                    
    // timezoneurl = timezoneurl+"location="+lat+","+lng+"&timestamp=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();
}

你打电话给哪个服务?你真的想和我们分享你的钥匙吗?
S
Stone

对于我们这些使用 Javascript 并希望通过 Google API 从邮政编码获取时区的人来说,这是一种方法。

通过地理定位获取纬度/经度通过将时区传递到时区 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);

I
Ito

如果您希望避免使用 Web 服务,则可以从浏览器中检索该信息,如下所示:

var d = new Date();
var usertime = d.toLocaleString();

//some browsers / OSs provide the timezone name in their local string
var tzsregex = /\b(ACDT|ACST|ACT|ADT|AEDT|AEST|AFT|AKDT|AKST|AMST|AMT|ART|AST|AWDT|AWST|AZOST|AZT|BDT|BIOT|BIT|BOT|BRT|BST|BTT|CAT|CCT|CDT|CEDT|CEST|CET|CHADT|CHAST|CIST|CKT|CLST|CLT|COST|COT|CST|CT|CVT|CXT|CHST|DFT|EAST|EAT|ECT|EDT|EEDT|EEST|EET|EST|FJT|FKST|FKT|GALT|GET|GFT|GILT|GIT|GMT|GST|GYT|HADT|HAEC|HAST|HKT|HMT|HST|ICT|IDT|IRKT|IRST|IST|JST|KRAT|KST|LHST|LINT|MART|MAGT|MDT|MET|MEST|MIT|MSD|MSK|MST|MUT|MYT|NDT|NFT|NPT|NST|NT|NZDT|NZST|OMST|PDT|PETT|PHOT|PKT|PST|RET|SAMT|SAST|SBT|SCT|SGT|SLT|SST|TAHT|THA|UYST|UYT|VET|VLAT|WAT|WEDT|WEST|WET|WST|YAKT|YEKT)\b/gi;

//in other browsers the timezone needs to be estimated based on the offset
var timezonenames = {"UTC+0":"GMT","UTC+1":"CET","UTC+2":"EET","UTC+3":"EEDT","UTC+3.5":"IRST","UTC+4":"MSD","UTC+4.5":"AFT","UTC+5":"PKT","UTC+5.5":"IST","UTC+6":"BST","UTC+6.5":"MST","UTC+7":"THA","UTC+8":"AWST","UTC+9":"AWDT","UTC+9.5":"ACST","UTC+10":"AEST","UTC+10.5":"ACDT","UTC+11":"AEDT","UTC+11.5":"NFT","UTC+12":"NZST","UTC-1":"AZOST","UTC-2":"GST","UTC-3":"BRT","UTC-3.5":"NST","UTC-4":"CLT","UTC-4.5":"VET","UTC-5":"EST","UTC-6":"CST","UTC-7":"MST","UTC-8":"PST","UTC-9":"AKST","UTC-9.5":"MIT","UTC-10":"HST","UTC-11":"SST","UTC-12":"BIT"};

var timezone = usertime.match(tzsregex);
if (timezone) {
    timezone = timezone[timezone.length-1];
} else {
    var offset = -1*d.getTimezoneOffset()/60;
    offset = "UTC" + (offset >= 0 ? "+" + offset : offset);
    timezone = timezonenames[offset];
}

//there are 3 variables can use to see the timezone
// usertime - full date
// offset - UTC offset time
// timezone - country

console.log('Full Date: ' + usertime);
console.log('UTC Offset: ' + offset);
console.log('Country Code Timezone: ' + timezone);

在我目前的情况下,它正在打印:

完整日期:‎27‎/‎01‎/‎2014‎‎16‎:‎53‎:‎37 UTC 偏移量:UTC-3 国家代码时区:BRT

希望它会有所帮助。


尽管我感谢您为此付出了一些努力,但请注意:1) 时区不是固定偏移量 2) 时区缩写不是标准化的或唯一的标识符 3) 这已经用 jsTimeZoneDetect 完成了,更准确地说。 4)您的答案与问题不符。问题是如何从纬度和经度坐标确定时区。
M
Maximus Su

函数 jsonpRequest(url, data) { let params = ""; for (let key in data) { if (data.hasOwnProperty(key)) { if (params.length == 0) { params += "?"; } 其他 { 参数 += "&"; } let encodedKey = encodeURIComponent(key);让 encodeValue = encodeURIComponent(data[key]);参数+=编码键+“=”+编码值; } } let script = document.createElement('script'); script.src = 网址 + 参数; document.body.appendChild(脚本); } function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition); } else { x.innerHTML = "此浏览器不支持地理位置。"; } } 让 lat_ini=[];让 lon_ini=[];函数 showPosition(position) { lat_ini= position.coords.latitude; lon_ini=位置.coords.longitude; } ////行之间的延迟时间 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /////// function getGMT() { getfinalGMT() getLocation() async function sample() { await sleep(2000);让 lat_str=lat_ini.toString();让 lng_str=""+lon_ini.toString();让 url = "https://api.opencagedata.com/geocode/v1/json";让数据 = { 回调:“displayGMT”,q:lat_str + lng_str,键:“fac4471073a347019196c1291e6a97d7”} jsonpRequest(url, data) } sample(); } 让 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;让 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_str,键:“fac4471073a347019196c1291e6a97d7”}jsonpRequest(url,数据)}让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 { 背景:线性梯度(向右,hsl(200, 100%, 50%),hsl(175, 100%, 50%));显示:弯曲;证明内容:中心;对齐项目:居中;最小高度:100vh;溢出:隐藏; } .clock { 宽度:200px;高度:200px;背景色:rgba(255, 255, 255, .8);边界半径:50%;边框:2px纯黑色;位置:相对; } .clock .number { --rotation: 0;位置:绝对;宽度:100%;高度:100%;文本对齐:居中;变换:旋转(var(--rotation));字体大小:1.5rem; } .clock .number1 { --rotation: 30deg; } .clock .number2 { --rotation: 60deg; } .clock .number3 { --旋转:90度; } .clock .number4 { --旋转:120度; } .clock .number5 { --旋转:150度; } .clock .number6 { --旋转:180度; } .clock .number7 { --rotation: 210deg; } .clock .number8 { --rotation: 240deg; } .clock .number9 { --rotation: 270deg; } .clock .number10 { --rotation: 300deg; } .clock .number11 { --rotation: 330deg; } .clock .hand { --rotation: 0;位置:绝对;底部:50%;左:50%;边框:1px 纯白色;边框左上角半径:10px;边框右上角半径:10px;变换原点:底部; z 指数:10;变换: translateX(-50%) 旋转(calc(var(--rotation) * 1deg)); } .clock::after { 内容:'';位置:绝对;背景颜色:黑色; z 指数:11;宽度:15px;高度:15px;最高:50%;左:50%;变换:翻译(-50%,-50%);边界半径:50%; } .clock .hand.second { 宽度:3px;高度:45%;背景颜色:红色; } .clock .hand.minute { 宽度:7px;高度:40%;背景颜色:黑色; } .clock .hand.hour { 宽度:10px;高度:35%;背景颜色:黑色; } /* 仅背景样式 */ @import url('https://fonts.googleapis.com/css?family=Raleway'); * {字体系列:Raleway; } .side-links { 位置:绝对;顶部:15px;右:15px; } .side-link { 显示:弹性;对齐项目:居中;证明内容:中心;文字装饰:无;边距底部:10px;白颜色;宽度:180px;填充:10px 0;边框半径:10px; } .side-link-youtube { 背景颜色:红色; } .side-link-twitter { 背景颜色:#1DA1F2; } .side-link-github { 背景颜色:#6e5494; } .side-link-text { margin-left: 10px;字体大小:18px; } .side-link-icon { 颜色:白色;字体大小:30px; }



< button class="text" onClick="getLocation()">Location

< /div>
1
2
< div class="number number3">3
4
5
6
7
8
9
10
11
12


伙计们,您必须将代码复制并粘贴到新的浏览器中,因为代码片段不允许我们提示用户的位置
希望大家欣赏
输入 lat 和 lng 后,按位置,GMT 然后激活时钟
我真的不认为你打算与我们分享你的 API 密钥到 opencagedata,是吗?您可以简单地描述这个 API,而不是转储代码。
好吧,有些人只需要看一个api的回调函数示例就可以更好地理解

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅