2010-03-09 11 views
13

Dado: LDAP almacena la ubicación de los usuarios.Ubicación basada en Timezone Retrieval

¿Cómo manejo sus husos horarios utilizando su ubicación? Se aceptan todos los punteros, se prefiere el lenguaje Java.

Gracias de antemano.

+0

Esta respuesta es grande: http://stackoverflow.com/a/16086964/1121497 –

Respuesta

8

Esto depende de la información que contiene la "ubicación"? De alguna manera, necesitaría asignar la ubicación a un nombre de zona horaria, preferiblemente los nombres de zona horaria de estilo Olson, porque son más detallados y fáciles de mapear, ya que son ubicaciones en sí mismas.

Si se trata de direcciones aproximadas (como país y ciudad más o menos), varios servicios de geolocalización incluyen zonas horarias en su información, por lo que puede llamar a estos servicios y ver.

Si se trata de una geolocalización con latitud y longitud, un sitio llamado Earthtools puede proporcionarle la zona horaria. http://www.earthtools.org/webservices.htm#timezone

Hay esta base de datos que proporciona asignaciones de las ciudades y países de zonas horarias: http://citytimezones.info/cms/pending_requests.htm

Por desgracia, utiliza los nombres de zona horaria de Windows, pero se puede partir de estos datos http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml Unicode.org para mapear entre los nombres de zona horaria de Windows y el Olson TZ nombres.

+0

ciudad, estado, país – samsina

+0

@samsina: Actualización con algunos enlaces que podrían ayudar. –

+0

Ver también [esta entrada wiki de la comunidad] (http://stackoverflow.com/q/16086962/634824) –

0

realidad no he hecho esto, pero el siguiente debería funcionar:

  1. Puede utilizar primero GeoGoogle biblioteca de Java para obtener la longitud/latitud de la ciudad-estado-país.

  2. A continuación, puede utilizar EarthTools (y algo de código Java de su preferencia) mencionado por Lennart para obtener la zona horaria :)

0

Estamos utilizando el MaxMind GeoIP database para obtener información sobre la ubicación de un usuario . Tienen una versión paga (99.8% de precisión) y free version (99.5% de precisión).

También le proporcionan API en Java, C, PHP, etc. que le permitirán consultar su base de datos que puede descargar y conservar localmente (actualizaciones provistas cada mes). La base de datos le brinda información sobre la ciudad, el estado, el país, etc. del cliente sobre la base de las direcciones IP.

Espero que esto ayude.

+0

También lo uso, pero no da ninguna información sobre la zona horaria (uso la versión gratuita, no uso 't saber acerca de la versión paga) –

0
Try this code for use Google Time Zone API from Java: 
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; 

     // String request = "http://ws.geonames.org/timezone?lat="+Latitude+"&lng="+ Longitude+ "&style=full"; 


     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=true 

     String request = "https://maps.googleapis.com/maps/api/timezone/xml?location="+Latitude+","+ Longitude+ "&timestamp="+tsLong +"&sensor=true"; 

     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; 

} 

y usarlo con:

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

este código es tan malo que hace sangrar mis ojos –