Enlem ve boylam koordinatlarını kullanarak bir konumdan saat dilimi nasıl alınır?


310

StackOverflow ile ilgili olarak bir saat dilimini bir konumdan çözme hakkında çok fazla soru var. Bu topluluk wiki'si, geçerli tüm yanıtları birleştirmeye yönelik bir girişimdir.

Lütfen cevabımı güncelleyin veya uygun gördüğünüz şekilde kendiniz ekleyin.

Soru
Bir konumun enlemi ve boylamı göz önüne alındığında, o konumda hangi saat diliminin yürürlükte olduğunu nasıl bilebilirsiniz?

Çoğu durumda, bir IANA / Olson zaman dilimi kimliği arıyoruz, ancak bazı hizmetler yalnızca bir UTC ofseti veya başka bir saat dilimi tanımlayıcısı döndürebilir. Ayrıntılar için lütfen saat dilimi etiketi bilgilerini okuyun .


2
Fark ettiğim bir şey, saat dilimini belirlerken herhangi bir UTC zaman damgası gereksiniminin olmamasıdır. Örneğin, Londra'daki bir uzun / lat, saat diliminin GMT veya BST (İngiliz Yaz Saati / yaz saati uygulaması) olduğunu belirlemek için yeterli değildir. Kesinlikle doğru zaman dilimini belirlemek için lat, long ve UTC zaman damgasına ihtiyacınız vardır.
Michael Waterfall

4
@MichaelWaterfall - GMT (UTC + 0000) veya BST (UTC + 0100) olup olmadığınızı belirlemek için - evet, kesinlikle haklısınız. Fakat bunlar zaman dilimi tanımlayıcıları değil , zaman dilimi ofsetleri . Her ikisi de "Europe/London"IANA zaman dilimi veritabanının aynı zaman dilimi tanımlayıcısı tarafından kapsanmaktadır .
Matt Johnson-Pint

Tamam, ve belirli bir saat dilimi tanımlayıcısıyla bir zaman oluşturduktan sonra (gerekirse) yaz saati ofseti eklenecek mi?
Michael Waterfall

@Michael - belirli bir uygulamaya bağlıdır, ancak genellikle evet.
Matt Johnson-Pint

1
Yine de UTC zaman damgası gerekebilir. Örneğin Rusya, son 6 yıl için zaman dilimlerini sınırlarını 4 kez değiştiriyor. en.wikipedia.org/wiki/Time_in_Russia
Arnial

Yanıtlar:


422

Saat Dilimi Konumu Web Hizmetleri

Ham Zaman Dilimi Sınır Verileri

  • Saat Dilimi Sınır Oluşturucu - OpenStreetMaps harita verilerinden saat dilimi şekil dosyaları oluşturur. Kıyı şeridinin yakınındaki karasularını içerir.

Aşağıdaki projeler daha önce saat dilimi sınır verilerinin kaynakları olmuştur, ancak artık aktif olarak tutulmamaktadır.

  • tz_world - Eric Muller'den orijinal şekil dosyası verileri
  • whereearear - timeezone - WOEDB verileri içeren GeoJSON sürümü birleştirildi

Zaman Dilimi Coğrafi Konum Çevrimdışı Uygulamalar

Timezone Boundary Builder verilerini kullanan uygulamalar

Eski tz_world verilerini kullanan uygulamalar

Web servislerinden birini çağıran kütüphaneler

Kendi kendine barındırılan web hizmetleri

Diğer fikirler

Başkalarını biliyorsanız lütfen bu listeyi güncelleyin

Ayrıca, en yakın şehir yaklaşımının "doğru" sonucu vermeyebileceğini, sadece bir tahmin sağlayabileceğini unutmayın.

Windows Bölgelerine Dönüştürme

Listelenen yöntemlerin çoğu bir IANA zaman dilimi kimliği döndürür. TimeZoneInfo.NET sınıfında kullanmak için bir Windows saat dilimine dönüştürmeniz gerekiyorsa , TimeZoneConverter kitaplığını kullanın .

Zone.tab kullanmayın

Tz veritabanı adlı bir dosya içerir zone.tab. Bu dosya öncelikle kullanıcının seçebileceği saat dilimlerinin listesini sunmak için kullanılır. Her zaman dilimi için referans noktası için enlem ve boylam koordinatlarını içerir. Bu, bu noktaları vurgulayan bir harita oluşturulmasına izin verir. Örneğin , moment-zaman dilimi ana sayfasında gösterilen etkileşimli haritaya bakın .

Bu verileri enlem ve boylam koordinatlarından saat dilimini çözmek için kullanmak cazip gelse de, bunların sınır değil, nokta olduğunu düşünün. Yapabileceği en iyi şey , çoğu durumda doğru nokta olmayacak olan en yakın noktayı belirlemek olacaktır.

Aşağıdaki örneği düşünün:

                            Saat Dilimi Örnek Sanat

İki kare, her karedeki siyah noktanın zone.tab içinde bulunabilecekler gibi referans konum olduğu farklı zaman dilimlerini temsil eder. Mavi nokta, saat dilimi bulmaya çalıştığımız konumu temsil eder. Açıkça, bu konum soldaki turuncu bölgededir, ancak referans noktasına en yakın mesafeye bakarsak, sağdaki yeşilimsi bölgeye gider.


1
GeoNames aslında ihtiyacım olan şey için mükemmel. Teşekkürler!
Luke

1
@Matt Ancak, anladığım kadarıyla, şu anda konum koordinatlarına göre UTC'den saat dilimi bilgisi ve ofset sağlayacak çevrimdışı veritabanı yok mu?
Martin

@MattJohnson nasıl ben geonames istemci kütüphaneleri kullanabilirsiniz
Erum

Bu harika bir liste, teşekkürler! Google bariz bir seçim gibi görünüyor, ama aslında Londra'nın GMT'de olduğunu söylerken şaşırdım, aslında şu anda BST'de. New York için doğru yaz ayarlaması yapıldı.
lewis

8
Bu yeni Google API oranları çok zor. 7/18 itibariyle 1 dolar için 200 talep. Bu 10 kat artış.
Chris Lukic


8

Bizler Teleport yeni başladık API doldu açılması ve usecases biri de koordinatlar için TZ bilgilerini teşhir edilir.

Örneğin, mevcut tüm TZ bilgilerimizi koordinatlar için aşağıdaki şekilde talep edebiliriz:

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"'

Bu aşağıdakileri döndürür

{
  "_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"
}

Örnekte JSON ayrıştırma için ./jq kullandım .


2
Paylaşım için teşekkürler. En yakın şehre yaklaşım mı yapıyor, yoksa çokgen noktasında bir yaklaşım mı kullanıyorsunuz? (Yukarıdaki iki kareye sahip diyagramıma bakın.)
Matt Johnson-Pint

3

Google'ın komut dosyası düzenleyicisini, bir gsheet'in içindeki timezoneName ve timeZoneId öğelerini almak için nasıl kullanabileceğiniz aşağıda açıklanmıştır.

1. Adım. Google'ın saat dilimi API'sı için bir API anahtarı edinin

Adım 2. Yeni bir gsheet oluşturun. 'Araçlar' menüsünün altında 'komut dosyası düzenleyici'yi tıklayın. Aşağıdaki kodu ekleyin:

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"];
}

Adım 3. getTimezone()İşlevinizi kaydedin ve yayınlayın ve yukarıdaki resimde gösterildiği gibi kullanın.


2

Geolocator.js'yi kullanabilirsinizKolayca saat dilimi ve daha fazlası için ...

Anahtar gerektiren Google API'larını kullanır. İlk olarak, coğrafi konum belirleyiciyi yapılandırın:

geolocator.config({
    language: "en",
    google: {
        version: "3",
        key: "YOUR-GOOGLE-API-KEY"
    }
});

Koordinatlarınız varsa TimeZone'u alın:

geolocator.getTimeZone(options, function (err, timezone) {
    console.log(err || timezone);
});

Örnek çıktı:

{
    id: "Europe/Paris",
    name: "Central European Standard Time",
    abbr: "CEST",
    dstOffset: 0,
    rawOffset: 3600,
    timestamp: 1455733120
}

Bulun ve ardından TimeZone ve daha fazlasını edinin

Koordinatlarınız yoksa, önce kullanıcı konumunu bulabilirsiniz.

Aşağıdaki örnek, koordinatları almak için önce HTML5 Coğrafi Konum API'sını deneyecektir. Başarısız olursa veya reddedilirse, Geo-IP araması ile koordinatları alır. Son olarak, saat dilimi ve daha fazlasını alacak ...

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

Örnek çıktı:

{
    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
}

1

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

Ve işte JSON verilerini kullanan iyi bir uygulama: 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());
    }
}

Bağlantılardan içerik de ekleyebilir misiniz?
Robert

1

açıklama: Aşağıda açıklanan liman işçisi resminin yazarıyım

Ben sardırırsın https://github.com/evansiroky/node-geo-tz çok basit bir liman işçisi-kapta

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

Liman işçisi konteynerini aşağıdakilerle başlatabilirsiniz:

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

Bu, 3000 numaralı bağlantı noktasındaki yerel ana makinenizdeki arama hizmetini açığa çıkarır. Ardından, saat dilimi araması yapabilirsiniz.

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

0

Geçerli NTP Zaman İstemcisi ile Java'dan Google Saat Dilimi API'sını kullanmak için bu kodu deneyin ve UTC_Datetime_from_timestamp dönüştürmesini düzeltin:

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;

}

Ve şununla kullan:

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

1
Bu basit bir görev için çok fazla kod gibi görünüyor. Orada tam bir NTP istemciniz var, bu iyi bir fikir olabilir - ancak zorunlu olarak gerekli değildir. Biraz inceltebilir misiniz lütfen?
Matt Johnson-Pint

0

Tamam burada doğru NTP Süresi olmayan kısa Sürüm:

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;

}

Ve şununla kullan:

GeoPoint gp = new GeoPoint(39.6034810,-119.6822510);
long Current_TimeZone_Time_l = get_time_zone_time_l(gp);

0

Geonames.org'u kullanmak istiyorsanız bu kodu kullanın. (Ancak geonames.org bazen çok yavaştır)

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;

 }

Ve şununla kullan:

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

0

Guppy'dan:

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

Bağlı yöntem America/Anchorage.dstbölgesininDstTzInfo

Amerika / Anchorage 'LMT-1 gün, 14:00:00 STD


Bence Guppy bir yazım hatası. Geopy ya da başka bir şey mi demek istiyorsun ?
Matt Johnson-Pint

0

Bunun, çoğu kişinin şüphelendiğinden daha karmaşık bir sorunun olduğunu bilmek gerçekten önemlidir. Uygulamada, birçoğumuz, en azından ölümcül sorunlarının toplu olarak tanımlanabildiği ve en aza indirilebildiği, "mümkün olduğunca çok sayıda vaka" için çalışan, çalışan bir kod dizisini kabul etmeye hazırız. Bunu tüm bunları ve OP'nin ruhunu göz önünde bulundurarak paylaşıyorum. Son olarak, konuma duyarlı bir zaman nesnesine sahip olmak (ve daha da önemlisi bu wiki'den sonra gelen zaman nesneleriyle ortalama uygulamaların kalitesini yükseltmek için) GPS'i zaman dilimine dönüştürmeye çalışan diğerlerine pratik değer için: Python'da ne oluşturduğumu (lütfen düzenlemekten çekinmeyin):

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)

Teşekkürler, ancak bu , ana topluluk wiki yanıtında listelenen pytzwhere kullanan bazı kodlara benziyor . Pytzwhere ile pytz'ın nasıl birleştirileceğine dair bir örnek vermek isterseniz, bunu pytzwhere projesinin kendisine bir PR olarak göndermek isteyebilirsiniz. Burada sadece pytzwhere bunlardan biri olan lat / lon to tz çözümleri arıyoruz.
Matt Johnson-Pint

0
  1. Zaman dilimleri için geojson verilerine sahip birkaç çevrimiçi kaynak vardır ( işte bir , işte başka)

  2. Geojson koordinatlarından ( düzgün [python], GEOS [c ++], JTS [java], NTS [.net]) çokgen nesneleri oluşturmak için bir geometri kitaplığı kullanın .

  3. Lat / lng'nizi bir nokta nesnesine dönüştürün (ancak kitaplığınız bunu temsil eder) ve saat dilimi çokgeniyle kesişip kesişmediğini kontrol edin.

    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

enlem ve boylam kullanarak geçerli konumun saat dilimini al kodun benim için çalıştı

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

11
Hangi hizmeti arıyorsun? Ve yaptın gerçekten bizimle anahtarlarınızı paylaşmak istiyorum ??
Matt Johnson-Pint

0

Javascript kullanan ve Google API'ları aracılığıyla bir posta kodundan bir saat dilimi almak isteyenler için burada bir yöntem var.

  1. Yer / konum aracılığıyla lat / lng getir
  2. saat dilimi API'sına geçirerek saat dilimini getir .
    • Kullanılması Luxon zaman dilimi dönüşüm için buraya.

Not: Anladığım kadarıyla, posta kodları ülkeler arasında benzersiz değildir, bu nedenle bu muhtemelen ABD'de kullanım için uygundur.

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

-2

  function jsonpRequest(url, data)
{
    let params = "";
    for (let key in data)
    {
        if (data.hasOwnProperty(key))
        {
            if (params.length == 0)
            {
                params += "?";
            }
            else
            {
                params += "&";
            }
            let encodedKey = encodeURIComponent(key);
            let encodedValue = encodeURIComponent(data[key]);
            params += encodedKey + "=" + encodedValue;
         }
    }
    let script = document.createElement('script');
    script.src = url + params;
    document.body.appendChild(script);
}

function getLocation() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    x.innerHTML = "Geolocation is not supported by this browser.";
  }
}
let lat_ini=[]; let lon_ini=[];
function showPosition(position) {
  lat_ini= position.coords.latitude;
  lon_ini= position.coords.longitude;
}
////delay time between lines
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
///////
function getGMT()
{
  getfinalGMT()
  getLocation()
  async function sample() {
    await sleep(2000);
let lat_str=lat_ini.toString();
let lng_str=" "+lon_ini.toString();

  let url = "https://api.opencagedata.com/geocode/v1/json";
  let data = {
    callback: "displayGMT",
    q: lat_str + lng_str,
    key: "fac4471073a347019196c1291e6a97d7"
  }
  jsonpRequest(url, data)
}
 sample();
 }
let 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; let lng=document.getElementById("lng_id").value;
let lat_str=lat.toString();
let lng_str=" "+lng.toString();

  let url = "https://api.opencagedata.com/geocode/v1/json";
  let data = {
    callback: "displayfinalGMT",
    q: lat + lng_str,
    key: "fac4471073a347019196c1291e6a97d7"
  }
  jsonpRequest(url, data)
 }
let 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 {
  background: linear-gradient(to right, hsl(200, 100%, 50%), hsl(175, 100%, 50%));
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  overflow: hidden;
}

.clock {
  width: 200px;
  height: 200px;
  background-color: rgba(255, 255, 255, .8);
  border-radius: 50%;
  border: 2px solid black;
  position: relative;
}

.clock .number {
  --rotation: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  text-align: center;
  transform: rotate(var(--rotation));
  font-size: 1.5rem;
}

.clock .number1 { --rotation: 30deg; }
.clock .number2 { --rotation: 60deg; }
.clock .number3 { --rotation: 90deg; }
.clock .number4 { --rotation: 120deg; }
.clock .number5 { --rotation: 150deg; }
.clock .number6 { --rotation: 180deg; }
.clock .number7 { --rotation: 210deg; }
.clock .number8 { --rotation: 240deg; }
.clock .number9 { --rotation: 270deg; }
.clock .number10 { --rotation: 300deg; }
.clock .number11 { --rotation: 330deg; }

.clock .hand {
  --rotation: 0;
  position: absolute;
  bottom: 50%;
  left: 50%;
  border: 1px solid white;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  transform-origin: bottom;
  z-index: 10;
  transform: translateX(-50%) rotate(calc(var(--rotation) * 1deg));
}

.clock::after {
  content: '';
  position: absolute;
  background-color: black;
  z-index: 11;
  width: 15px;
  height: 15px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}

.clock .hand.second {
  width: 3px;
  height: 45%;
  background-color: red;
}

.clock .hand.minute {
  width: 7px;
  height: 40%;
  background-color: black;
}

.clock .hand.hour {
  width: 10px;
  height: 35%;
  background-color: black;
}














/* Background Styles Only */

@import url('https://fonts.googleapis.com/css?family=Raleway');

* {
    font-family: Raleway;
}

.side-links {
  position: absolute;
  top: 15px;
  right: 15px;
}

.side-link {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  margin-bottom: 10px;
  color: white;
  width: 180px;
  padding: 10px 0;
  border-radius: 10px;
}

.side-link-youtube {
  background-color: red;
}

.side-link-twitter {
  background-color: #1DA1F2;
}

.side-link-github {
  background-color: #6e5494;
}

.side-link-text {
  margin-left: 10px;
  font-size: 18px;
}

.side-link-icon {
  color: white;
  font-size: 30px;
}
   <input type="text" id="lat_id" placeholder="lat"><br><br>
  <input type="text" id="lng_id" placeholder="lng"><br><br>
<button class="text" onClick="getLocation()">Location</button>
<button class="text" onClick="getGMT()"> GMT</button>
<button class="text" onClick="activate_clock()"> Activate</button>
<div class="clock">
  <div class="hand hour" data-hour-hand></div>
  <div class="hand minute" data-minute-hand></div>
  <div class="hand second" data-second-hand></div>
  <div class="number number1">1</div>
  <div class="number number2">2</div>
  <div class="number number3">3</div>
  <div class="number number4">4</div>
  <div class="number number5">5</div>
  <div class="number number6">6</div>
  <div class="number number7">7</div>
  <div class="number number8">8</div>
  <div class="number number9">9</div>
  <div class="number number10">10</div>
  <div class="number number11">11</div>
  <div class="number number12">12</div>
</div>


Kod pasajı, kullanıcının yerini istememize izin vermediğinden, kodu kopyalayıp yeni bir tarayıcıya yapıştırmanız gerekecek
Maximus Su

Umarım sizleri takdir edersiniz
Maximus Su

Bir kez lat ve lng girin, konuma basın, GMT sonra saati etkinleştirin
Maximus Su

Gerçekten opencagedata için API anahtarınızı bizimle paylaşmak istediğinizi düşünmüyorum, değil mi? Kod dökümü yerine, bu API'yı tanımlayabilirsiniz.
Matt Johnson-Pint

Bazı insanların daha iyi anlamak için api için geri arama işlevinin bir örneğini görmesi gerekir
Maximus Su

-3

Bir web hizmetinden kaçınmayı tercih ederseniz, bu bilgileri tarayıcıdan şu şekilde alabilirsiniz:

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

Şu anki durumumda yazdırılıyor:

Tam Tarih: 27/01/2014 16: 53: 37 UTC Ayarı: UTC-3 Ülke Kodu Saat Dilimi: BRT

Umarım yardımcı olabilir.


Buna biraz çaba harcadığınız için teşekkür ederim, lütfen şunu fark edin: 1) Zaman dilimleri sabit ofsetler değildir 2) Zaman dilimi kısaltmaları standart değildir veya benzersiz tanımlayıcılar değildir 3) Bu zaten çok daha doğru bir şekilde jsTimeZoneDetect ile yapılmıştır . 4) Cevabınız soru ile eşleşmiyor. Soru, enlem ve boylam koordinatlarından bir saat diliminin nasıl belirleneceği idi .
Matt Johnson-Pint
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.