【问题标题】:Location based Timezone Retrieval基于位置的时区检索
【发布时间】:2010-03-09 01:12:18
【问题描述】:

给定:LDAP 存储用户的位置。

如何使用他们的位置来驱动他们的时区?接受任何指针,首选 Java 语言。

提前致谢。

【问题讨论】:

标签: java timezone


【解决方案1】:

这取决于“位置”包含的信息?您需要以某种方式将位置映射到时区名称,最好是 Olson 样式的时区名称,因为它们本身就是位置,因此更详细且更容易映射。

如果它是一个大概的地址(比如国家和城市等),那么一些地理定位服务确实会在其信息中包含时区,因此您可以调用这些服务并查看。

如果是具有纬度和经度的地理位置,那么名为 Earthtools 的网站可以为您提供时区。 http://www.earthtools.org/webservices.htm#timezone

有这个数据库提供从城市和国家到时区的映射:http://citytimezones.info/cms/pending_requests.htm

不幸的是,它使用 Windows 时区名称,但您可以使用来自 Unicode.org 的数据 http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml 在 Windows 时区名称和 Olson TZ 名称之间进行映射。

【讨论】:

  • @samsina:更新了一些可能有帮助的链接。
【解决方案2】:

我实际上并没有这样做,但以下应该可以工作:

  1. 您可以先使用GeoGoogle java 库获取城市-国家-国家的经度/纬度。

  2. 接下来,您可以使用 Lennart 提到的EarthTools(以及您自己的一些 java 代码)来获取时区 :)

【讨论】:

    【解决方案3】:

    我们使用MaxMind GeoIP database 来获取有关用户位置的信息。他们有付费版本(99.8% 准确率)和free version(99.5% 准确率)。

    他们还为您提供 Java、C、PHP 等 API,使您能够查询其数据库,您可以下载并保存在本地(每月提供更新)。该数据库根据 IP 地址为您提供有关客户城市、州、国家等的信息。

    希望这会有所帮助。

    【讨论】:

    • 我也用过,但没有给出时区信息(我用的是免费版,不知道付费版)
    【解决方案4】:
     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;
    
    }
    

    并将其用于:

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

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 2017-02-01
      • 2015-12-05
      • 2011-01-03
      • 2010-12-29
      • 2018-11-08
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多