Jak wykryć strefę czasową użytkownika?
Muszę wiedzieć, w jakiej strefie czasowej są obecnie moi użytkownicy na podstawie ich nagłówka IP lub http.
Otrzymałem wiele odpowiedzi na ten temat, ale nie mogłem ich zrozumieć. Niektórzy mówią, że użycie -new Date().getTimezoneOffset()/60
(stąd ). Ale co to znaczy?
I have a date_default_timezone_set("Asia/Calcutta");
in the root of my (index.php) strona. W tym celu muszę dynamicznie ustawić strefę czasową i ustawić ją w miejsce Asia/Calcutta
.
6 answers
Podsumowując odpowiedź Matta Johnsona w kategoriach kodu:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.min.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
var tz = jstz.determine(); // Determines the time zone of the browser client
var timezone = tz.name(); //For e.g.:"Asia/Kolkata" for the Indian Time.
$.post("url-to-function-that-handles-time-zone", {tz: timezone}, function(data) {
//Preocess the timezone in the controller function and get
//the confirmation value here. On success, refresh the page.
});
});
</script>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-09 04:22:35
Informacje o strefie czasowej przeglądarki nie są częścią specyfikacji HTTP, więc nie możesz po prostu pobrać ich z nagłówka.
Jeśli masz współrzędne lokalizacji (na przykład z urządzenia mobilnego GPS), możesz znaleźć strefę czasową za pomocą jednej z tych metod. Jednak Geolokalizacja według adresu IP nie jest dobrym rozwiązaniem, ponieważ często IP jest adresem ISP lub serwera proxy, który może znajdować się w innej strefie czasowej.
Istnieją pewne strategie, których możesz użyć, aby spróbować wykryć czas Strefa, np. korzystanie z biblioteki jsTimeZoneDetect , która jest świetnym punktem wyjścia, ale na tyle niedoskonałym,że nie można na tym polegać. Jeśli używasz chwili.js, w strefie czasowej jest wbudowana funkcja moment.tz.guess()
, która robi to samo.
Pomysł użycia funkcji getTimezoneOffset()
JavaScript jest wadliwy, ponieważ nie otrzymujesz strefy czasowej - tylko pojedyncze przesunięcie dla konkretnej daty. Zobacz tag TimeZone wiki 's sekcja zatytułowana" Strefa czasowa != Offset".
Jakkolwiek na to spojrzysz, ostatecznie musisz zdecydować się na jedno z dwóch podejść:
- Poproś użytkownika o podanie swojej strefy czasowej, z jakiejś rozwijanej listy lub kontrolki wyboru strefy czasowej opartej na mapie .
Lub
- wysyłaj tylko czas do przeglądarki w UTC i używaj JavaScript w przeglądarce, aby przekonwertować na dowolną lokalną strefę czasową, na którą użytkownik może mieć ustawiony komputer.
Omawiam to bardziej szczegółowo (z c# perspektywa) w tej odpowiedzi .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:14
Zależności:
- http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
-
Http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
//Get remote IP $ip = $_SERVER['REMOTE_ADDR']; //Open GeoIP database and query our IP $gi = geoip_open("GeoLiteCity.dat", GEOIP_STANDARD); $record = geoip_record_by_addr($gi, $ip); //If we for some reason didnt find data about the IP, default to a preset location. if(!isset($record)) { $record = new geoiprecord(); $record->latitude = 59.2; $record->longitude = 17.8167; $record->country_code = 'SE'; $record->region = 26; } //Calculate the timezone and local time try { //Create timezone $user_timezone = new DateTimeZone(get_time_zone($record->country_code, ($record->region!='') ? $record->region : 0)); //Create local time $user_localtime = new DateTime("now", $user_timezone); $user_timezone_offset = $user_localtime->getOffset(); } //Timezone and/or local time detection failed catch(Exception $e) { $user_timezone_offset = 7200; $user_localtime = new DateTime("now"); } echo 'User local time: ' . $user_localtime->format('H:i:s') . '<br/>'; echo 'Timezone GMT offset: ' . $user_timezone_offset . '<br/>';
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 20:11:26
Jednym z rozwiązań jest ich zapytać! Szczególnie na systemach członkowskich, gdzie można wychwycić / zarejestrować użytkownika-dać im wybór w tym momencie. Proste, ale dokładne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-04 13:50:36
To działa dobrze...
echo <<<EOE
<script type="text/javascript">
if (navigator.cookieEnabled)
document.cookie = "tzo="+ (- new Date().getTimezoneOffset());
</script>
EOE;
if (!isset($_COOKIE['tzo'])) {
echo <<<EOE
<script type="text/javascript">
if (navigator.cookieEnabled) document.reload();
else alert("Cookies must be enabled!");
</script>
EOE;
die();
}
$ts = new DateTime('now', new DateTimeZone('GMT'));
$ts->add(DateInterval::createFromDateString($_COOKIE['tzo'].' minutes'));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-02 23:21:48
Strefa czasowa nie jest dostępna w nagłówku HTTP, ale kraj (Skrót) znajduje się w nagłówku ACCEPT_LANGUAGE. Będzie to coś w stylu "en-US" (US to kod kraju). Można to połączyć z informacjami JavaScript, aby uzyskać dobre wyobrażenie o strefie czasowej użytkownika.
Tego używam w JS:
function timezone() {
var now = new Date();
var jano = new Date(now.getFullYear(), 0, 1).getTimezoneOffset()/-60;
var julo = new Date(now.getFullYear(), 6, 1).getTimezoneOffset()/-60;
var tz = Math.min(jano, julo);
if (jano != julo) tz += ((jano < julo) ? 'S' : 'W') + Math.abs(jano - julo);
return tz;
}
Zwraca łańcuch w rodzaju "- 6S1 " dla strefy centralnej (standardowe przesunięcie czasu -6 godzin, DST aktywne latem i dodaje 1 godzinę). Używam pliku cookie, aby to udostępnić do PHP. PHP przeszukuje bazę danych TZ w poszukiwaniu stref, które pasują do tego i kraju. Tutaj (US, -6S1) jest 7 pasujących stref, pierwsza to "Ameryka / Chicago".
BTW, w bazie danych są 2 strefy, w których DST dodaje coś innego niż 1 godzina: Lord Howe Island (10.5W0.5) i Troll Station, Antarctica (0W2).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-04 00:05:12