2013-04-18 2 views
200

Слишком много вопросов о StackOverflow о разрешении часового пояса из местоположения. Эта вики сообщества - попытка консолидировать все действительные ответы.Как получить часовой пояс из местоположения с использованием координат широты и долготы?

Обновите свой ответ или добавьте свои собственные, как вы сочтете нужным.

Вопрос
Учитывая широту и долготу места, как узнать, что часовой пояс в действительности в этом месте?

В большинстве случаев мы ищем идентификатор часового пояса IANA/Olson, хотя некоторые службы могут возвращать только сдвиг UTC или какой-либо другой идентификатор часового пояса. Пожалуйста, прочитайте timezone tag info.

+2

Одна вещь, которую я заметил, это отсутствие какого-либо требования к отметке времени UTC при определении часового пояса. Например, длинный/лат в Лондоне недостаточно для определения погоды, часовой пояс GMT или BST (британское летнее время/летнее время). Поэтому, конечно, для определения правильного часового пояса вам понадобятся lat, long и временная метка UTC. –

+2

@MichaelWaterfall - Чтобы определить, находитесь ли вы в GMT (UTC + 0000) или BST (UTC + 0100) - да, вы абсолютно правы. Но это временные интервалы * смещения *, а не идентификаторы часовых поясов. Оба они покрываются одним и тем же идентификатором часового пояса «Европа/Лондон» в базе данных часовых поясов IANA. –

+0

А в порядке, и смещение дневного света будет добавлено (если требуется) после рендеринга времени с заданным идентификатором часового пояса? –

ответ

253

часовых поясов Адрес Web Services

Raw Time Zone Boundary данные

  • Timezone Boundary Builder - строят часовые пояса шейпфайлов от картографических данных OpenStreetMaps. Включает в себя территориальные воды вблизи береговых линий.

Следующие проекты ранее были источниками данных о границах часовых поясов, но больше не поддерживаются в активной эксплуатации.

  • tz_world - оригинальный шейпфайл данные Эрика Мюллер
  • whereonearth-timezone - версия GeoJSON с данными WOEDB объединена в

Time Zone геолокация Оффлайн реализации

Реализация, использующую часовой пояс, Boundary Данные изготовителя

Реализации, которые используют старые данные tz_world

Библиотеки, которые называют один из веб-сервисов

  • timezone - Ruby gem, который вызывает GeoNames
  • AskGeo имеет свои собственные библиотеки для вызова из Java или .Net
  • GeoNames есть клиентские библиотеки уже есть на все

Другие идеи

Пожалуйста, обновите этот список, если вы знаете о любых других

Кроме того, обратите внимание, что ближайший город-подход не может дать результат «правильный», только приближение.

Преобразование в Windows, зон

Большинство перечисленных методов возвращает часовой пояс идентификатор IANA. Если вам нужно преобразовать в часовой пояс Windows для использования с классом TimeZoneInfo в .NET, используйте библиотеку TimeZoneConverter.

Не используйте zone.tab

tz database включает в себя файл с именем zone.tab. Этот файл в основном используется для представления списка часовых поясов для пользователя. Он включает координаты широты и долготы для точки отсчета для каждого часового пояса. Это позволяет создать карту, выделяя эти точки. Например, см. Интерактивную карту, показанную на the moment-timezone home page.

Хотя может быть заманчиво использовать эти данные для разрешения часового пояса из координат широты и долготы, считайте, что это точки, а не границы.Лучше всего было бы определить ближайший пункт, что во многих случаях не будет правильным.

Рассмотрим следующий пример:

                            Time Zone Example Art

Два квадрата представляют различные временные зоны, где черная точка в каждом квадрате является ссылкой местоположение, например, то, что можно найти в zone.tab. Синяя точка представляет собой местоположение, в котором мы пытаемся найти часовой пояс. Очевидно, что это место находится в оранжевой зоне слева, но если мы просто посмотрим на ближайшее расстояние до контрольной точки, оно будет разрешено к зеленоватой зоне справа.

+1

GeoNames на самом деле идеально подходит для меня. Благодаря! – Luke

+1

@Matt Однако, насколько я понимаю, на данный момент нет автономной базы данных, которая обеспечивала бы информацию о часовом поясе и смещение от UTC на основе координат местоположения? – Martin

+0

@MattJohnson Как я могу использовать клиентские библиотеки geonames – Erum

-1

Попробуйте этот код для использования Google Time Zone API из Java с текущим клиентом 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); 
+1

Это похоже на много кода для простой задачи. У вас есть полный NTP-клиент, который может быть хорошей идеей, но это необязательно требуется. Можете ли вы немного уменьшить его? –

+0

Да! Вот почему я не использую Java. У вас может быть больше шаблонов? – Jaseem

0

Хорошо здесь короткую версия без правильного 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); 
0

Если вы хотите использовать 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); 
-4

Если вы предпочитаете, чтобы избежать веб-службы, вы можете получить эту информацию из браузера, как это:

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 Offset: UTC-3 Код страна Timezone: BRT

Надеется, что это может быть полезным.

+0

Хотя я ценю, что вы вложили в это несколько усилий, поймите: 1) Часовые пояса не являются фиксированными смещениями. 2) Сокращения часовых поясов не являются стандартизованными или уникальными идентификаторами. 3) Это было сделано гораздо точнее с помощью [jsTimeZoneDetect] (http://pellepim.bitbucket.org/jstz/). 4) Ваш ответ не соответствует вопросу. Вопрос заключался в том, как определить часовой пояс ** из координат широты и долготы **. –

0

с помощью широты и долготы получить часовой пояс текущего местоположения ниже код работает для меня

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"; //&key=AIzaSyDZMS5Za6yG_66gAK8PL_KH1ZSS9NbWC";     
    // timezoneurl = timezoneurl+"location="+lat+","+lng+"&timestamp=1331161200";//&key=AIzaSyDZMS5Za6yG_66gAK8PL_KH1ZSS9NbWCbg"; 

    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(); 
} 
+11

Какую услугу вы вызываете? И ты действительно хотел поделиться своими ключами с нами? –

-1

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()); 
    } 
} 
+0

Можете ли вы также добавить контент из ссылок? – Robert

5

Мы в 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 синтаксического анализа.

+0

Спасибо за обмен. Использует ли подход ближайшего города, или вы используете подход «точка-в-полигон»? (См. Мою диаграмму с двумя квадратами выше.) –

-1

От Гуппи:

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 

Связанный метод America/Anchorage.dst из DstTzInfo

Америка/Анкоридж»LMT-1 день 14:00:00 STD

+0

Я думаю, что Guppy - опечатка. Вы имеете в виду [Geopy] (https://github.com/geopy/geopy) или что-то еще? –

+0

нет библиотеки geocoders :( – mousecoder

2

Вы можете использовать geolocator.js для легкого получение часовой пояс и многое другое ...

В нем используются API Google, которые требуют ключ. Итак, сначала настроить 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 
} 

Locate затем получить TimeZone и многое другое

Если у вас нет координат, вы можете сначала найти позицию пользователя.

Пример, приведенный ниже, сначала попросит API-интерфейс HTML5 Geolocation для получения координат. Если он терпит неудачу или отклонен, он получит координаты через Geo-IP look-up. Наконец, он получит часовой пояс и многое другое ...

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 
} 
0
  1. Есть несколько источников в Интернете, которые GeoJSON данных для часовых поясов (here's one, here's других)

  2. Используйте библиотеку геометрии для создания многоугольные объекты из координат геойсона (shapely [python], GEOS [C++], JTS [java], NTS [.net]).

  3. Преобразование вашего 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 = Polygon(coordinates) 
         point = Point(lng, lat) 
         if polygon.contains(point): 
          return tz 
    
0

Это действительно важно признать, что это более сложная задача, чем большинство заподозрит. На практике многие из нас также готовы принять рабочий набор кода, который работает для «как можно большего числа случаев», где по крайней мере его фатальные проблемы могут быть идентифицированы и сведены к минимуму в совокупности. Поэтому я публикую это со всем этим и духом OP в виду. Наконец, для практической ценности для других, которые пытаются преобразовать GPS в часовой пояс с конечной целью иметь чувствительный к местоположению объект времени (и, что более важно, помочь повысить качество средних реализаций с объектами времени, которые следуют из этой вики), здесь то, что я создал в 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) 
+0

Спасибо, но это выглядит как код, который использует [pytzwhere] (https://github.com/pegler/pytzwhere), который уже указан в главном ответе wiki сообщества. представите пример того, как объединить pytzwhere с pytz, вы можете представить это как PR для самого проекта pytzwhere. Здесь мы просто ищем решения lat/lon to tz, из которых pytzwhere является одним из них. –

2

Вот как вы можете использовать редактор сценариев Google, чтобы получить TimeZoneName и timeZoneId внутри gsheet.

Шаг 1. Get an API key для Google, часовой пояс API

Шаг 2. Создайте новый gsheet. В меню «tools» нажмите «Редактор сценариев». Добавьте следующий код:

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() функцию и использовать его, как показано на рисунке выше.

Смежные вопросы