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

在大多数情况下,我们正在寻找IANA/Olson时区id,尽管有些服务可能只返回UTC偏移量或其他一些时区标识符。详细信息请阅读时区标签信息。


当前回答

如果你不想使用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

希望对大家有所帮助。

其他回答

通过使用纬度和经度得到当前位置下面的时区代码为我工作

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

好的,这是没有正确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);

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

从古比鱼:

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的dst

美国/主播LMT-1天,STD 1400:00

尝试以下代码使用谷歌时区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);