Er det noen standard måte for en Web Server for å kunne fastslå en brukers tidssone på en webside?
Kanskje fra en HTTP-overskrift eller en del av brukeragenten streng?
Er det noen standard måte for en Web Server for å kunne fastslå en brukers tidssone på en webside?
Kanskje fra en HTTP-overskrift eller en del av brukeragenten streng?
Det er ingen HTTP-hoder som vil rapportere til kunder tidssone så langt selv om det har blitt foreslått å inkludere den i HTTP-spesifikasjonen.
Hvis det var meg, ville jeg nok prøve å hente tidssonen ved hjelp av clientJavaScript og deretter sende den til serveren ved hjelp av Ajax eller noe.
Javascript er den enkleste måten å få kundens lokal tid. Jeg vil foreslå å bruke en XMLHttpRequest
å sende tilbake lokal tid, og hvis det mislykkes, falle tilbake til tidssonen detektert basert på deres IP-adresse.
Såvidt geolocation, har jeg brukt MaxMind GeoIP på flere prosjekter, og det fungerer bra, men jeg er ikke sikker på om de gir tidssone data. Det er en tjeneste du betaler for, og de gir månedlige oppdateringer til databasen. De gir wrappers i flere web språk.
Den mest populære (== standard?) Måte å avgjøre hvilken tidssone jeg har sett rundt er rett og slett å spørre brukerne selv. Hvis nettstedet krever abonnement, kan dette bli lagret i brukernes profildata. For Anon brukere, kan datoene vises som UTC eller GMT eller noe slikt.
Jeg prøver ikke å være en smart aleck. Det er bare at noen ganger noen problemer har finere løsninger utenfor programmering sammenheng.
Magien alt synes å være i
visitortime.getTimezoneOffset()
Det er kult, jeg visste ikke om det. Virker det i IE, etc? Derfra bør du være i stand til å bruke JS til Ajax, informasjonskapsler, uansett. Jeg vil trolig gå cookie ruten selv.
Du må tillate brukeren å endre det selv. Vi prøvde å bruke geolocation (via MaxMind) for å gjøre dette en stund siden, og det var galt rimelig ofte - nok til å gjøre det ikke verdt å gjøre, så vi bare la brukeren sette den i profilen sin, og viser et varsel til brukere som har ikke satt deres ennå.
Noen som vet om noen tjenester som vil matche IP til geografisk plassering
Vel, heldig for deg at svaret kan bli funnet på vår egen Stackoverflow webside: Hvordan få land i henhold til en bestemt IP?
Spoiler: http://www.hostip.info/use.html
Hvis du tilfeldigvis være å bruke OpenID for autentisering, enkel registrering Extension vil løse problemet for godkjente brukere (Du må konvertere fra tz til numerisk).
Et annet alternativ ville være å antyde tidssonen fra brukerens agentens landet preferanse. Dette er en noe grov metode (ikke vil fungere for no-NO), men gir en god tilnærming.
-new Date().getTimezoneOffset()/60;
Metoden getTimezoneOffset()
vil trekke tid fra GMT og returnere antall minutter. Så hvis du bor i GMT-8, vil den returnere 480.
For å sette dette i timer, dividere med 60. Legg også merke til at skiltet er det motsatte av hva du trenger - det er beregning GMT er forskjøvet fra tidssonen, ikke tidssonen er forskjøvet fra GMT. For å fikse dette, bare multiplisere med -1.
Merk også at w3school sier:
Den returnerte verdien er ikke en konstant, på grunn av praksisen med å bruke sommertid.
Her er en artikkel (med kildekode) som forklarer hvordan du finner ut og bruke lokal tid i en ASP.NET (VB.NET, C #) program:
Kort sagt, er avhengig av den beskrevne tilnærming på Javascript i getTimezoneOffset
funksjonen, som returnerer verdien som er lagret i øktinformasjonskapsel og brukes av kode-bak for å justere tidsverdier mellom GMT og lokal tid. Det fine er at brukeren ikke trenger å angi tidssonen (koden gjør det automatisk). Det er mer involvert (det er derfor jeg link til artikkelen), men gitt kode gjør det veldig enkelt å bruke. Jeg mistenker at du kan konvertere logikken til PHP og andre språk (så lenge du forstår ASP.NET).
Med PHP date funksjonen vil du få datoen tiden av serveren der nettstedet er plassert. Den eneste måten å få bruker tid på er å bruke Javascript.
Men jeg foreslår at du, hvis området er registrering nødvendig da beste måten er å spørre brukeren mens registrering som obligatorisk felt. Du kan liste opp ulike tidssoner i registeret siden og lagre det i databasen. Etter dette hvis brukerpålogging til nettstedet så kan du sette standard tidssone for den økten som per brukernes valgt tidssone. Du kan angi en bestemt tidssone ved hjelp av PHP-funksjonen date_default_timezone_set
. Dette satte den angitte tidssonen for brukerne.
I utgangspunktet brukernes tidssonen går til klientsiden, så vi må bruke Javascript for dette.
Nedenfor er manuset for å få brukernes tidssone ved hjelp av PHP og Javascript.
<?php
#http://www.php.net/manual/en/timezones.php List of Time Zones
function showclienttime()
{
if(!isset($_COOKIE['GMT_bias']))
{
?>
<script type="text/javascript">
var Cookies = {};
Cookies.create = function (name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
} else {
var expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
this[name] = value;
}
var now = new Date();
Cookies.create("GMT_bias",now.getTimezoneOffset(),1);
window.location = "<?php echo $_SERVER['PHP_SELF'];?>";
</script>
<?php
} else {
$fct_clientbias = $_COOKIE['GMT_bias'];
}
$fct_servertimedata = gettimeofday();
$fct_servertime = $fct_servertimedata['sec'];
$fct_serverbias = $fct_servertimedata['minuteswest'];
$fct_totalbias = $fct_serverbias – $fct_clientbias;
$fct_totalbias = $fct_totalbias * 60;
$fct_clienttimestamp = $fct_servertime + $fct_totalbias;
$fct_time = time();
$fct_year = strftime("%Y", $fct_clienttimestamp);
$fct_month = strftime("%B", $fct_clienttimestamp);
$fct_day = strftime("%d", $fct_clienttimestamp);
$fct_hour = strftime("%I", $fct_clienttimestamp);
$fct_minute = strftime("%M", $fct_clienttimestamp);
$fct_second = strftime("%S", $fct_clienttimestamp);
$fct_am_pm = strftime("%p", $fct_clienttimestamp);
echo $fct_day.", ".$fct_month." ".$fct_year." ( ".$fct_hour.":".$fct_minute.":".$fct_second." ".$fct_am_pm." )";
}
showclienttime();
?>
Men som per mitt synspunkt, er det bedre å spørre for brukerne hvis registreringen er obligatorisk i prosjektet.
Her er en mer komplett måte.
Unntatt Under:
function TimezoneDetect(){
var dtDate = new Date('1/1/' + (new Date()).getUTCFullYear());
var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
var intMonth;
var intHoursUtc;
var intHours;
var intDaysMultiplyBy;
//go through each month to find the lowest offset to account for DST
for (intMonth=0;intMonth < 12;intMonth++){
//go to the next month
dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);
//To ignore daylight saving time look for the lowest offset.
//Since, during DST, the clock moves forward, it'll be a bigger number.
if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
intOffset = (dtDate.getTimezoneOffset() * (-1));
}
}
return intOffset;
}
Får TZ og DST fra JS (via Way Back Machine)
Bruke Unkwntech tilnærming, skrev jeg en funksjon ved hjelp av jQuery og PHP. Dette er testet og fungerer!
På PHP side der du vil ha tidssonen som en variabel, har denne kodebit et sted nær toppen av siden:
<?php
session_start();
$timezone = $_SESSION['time'];
?>
Dette vil lese økten variabelen "tid", som vi nå er i ferd med å skape.
På samme side, i, må du først og fremst omfatter jQuery:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
Også i, under jQuery, lim inn denne:
<script type="text/javascript">
$(document).ready(function() {
if("<?php echo $timezone; ?>".length==0){
var visitortime = new Date();
var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
$.ajax({
type: "GET",
url: "http://domain.com/timezone.php",
data: 'time='+ visitortimezone,
success: function(){
location.reload();
}
});
}
});
</script>
Du kan eller ikke har lagt merke til, men du må endre url til selve domenet.
En siste ting. Du lurer kanskje på hva pokker timezone.php er. Vel, det er ganske enkelt dette: (opprette en ny fil som heter timezone.php og peker på den med over url)
<?php
session_start();
$_SESSION['time'] = $_GET['time'];
?>
Hvis dette fungerer på riktig måte, vil det først laste siden, utføre Javascript, og oppdater siden. Du vil da kunne lese $ tidssone variabel og bruke det til din glede! Det returnerer gjeldende UTC / GMT tidssone offset (GMT -7) eller hva tidssone du er i.
javascript:
function maketimus(timestampz)
{
var linktime = new Date(timestampz * 1000);
var linkday = linktime.getDate();
var freakingmonths=new Array();
freakingmonths[0]="jan";
freakingmonths[1]="feb";
freakingmonths[2]="mar";
freakingmonths[3]="apr";
freakingmonths[4]="may";
freakingmonths[5]="jun";
freakingmonths[6]="jul";
freakingmonths[7]="aug";
freakingmonths[8]="sep";
freakingmonths[9]="oct";
freakingmonths[10]="nov";
freakingmonths[11]="dec";
var linkmonthnum = linktime.getMonth();
var linkmonth = freakingmonths[linkmonthnum];
var linkyear = linktime.getFullYear();
var linkhour = linktime.getHours();
var linkminute = linktime.getMinutes();
if (linkminute < 10)
{
linkminute = "0" + linkminute;
}
var fomratedtime = linkday + linkmonth + linkyear + " " + linkhour + ":" + linkminute + "h";
return fomratedtime;
}
bare gi din ganger i Unix tidsstempel format til denne funksjonen, javascript allerede kjenner tidssonen til brukeren.
som dette:
php:
echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';
dette vil alltid vise riktig tid basert på tidssonen personen har satt på sin datamaskin klokke, ingen grunn til å spørre noe til noen og lagre den i steder Takk Gud!
En enkel måte å gjøre det på er ved å bruke:
new Date().getTimezoneOffset();
Her er hvordan jeg gjør det. Dette vil sette PHP standard tidssone til brukerens lokale tidssone. Bare lim følgende på toppen av alle sidene dine:
<?php
session_start();
if(!isset($_SESSION['timezone']))
{
if(!isset($_REQUEST['offset']))
{
?>
<script>
var d = new Date()
var offset= -d.getTimezoneOffset()/60;
location.href = "<?php echo $_SERVER['PHP_SELF']; ?>?offset="+offset;
</script>
<?php
}
else
{
$zonelist = array('Kwajalein' => -12.00, 'Pacific/Midway' => -11.00, 'Pacific/Honolulu' => -10.00, 'America/Anchorage' => -9.00, 'America/Los_Angeles' => -8.00, 'America/Denver' => -7.00, 'America/Tegucigalpa' => -6.00, 'America/New_York' => -5.00, 'America/Caracas' => -4.30, 'America/Halifax' => -4.00, 'America/St_Johns' => -3.30, 'America/Argentina/Buenos_Aires' => -3.00, 'America/Sao_Paulo' => -3.00, 'Atlantic/South_Georgia' => -2.00, 'Atlantic/Azores' => -1.00, 'Europe/Dublin' => 0, 'Europe/Belgrade' => 1.00, 'Europe/Minsk' => 2.00, 'Asia/Kuwait' => 3.00, 'Asia/Tehran' => 3.30, 'Asia/Muscat' => 4.00, 'Asia/Yekaterinburg' => 5.00, 'Asia/Kolkata' => 5.30, 'Asia/Katmandu' => 5.45, 'Asia/Dhaka' => 6.00, 'Asia/Rangoon' => 6.30, 'Asia/Krasnoyarsk' => 7.00, 'Asia/Brunei' => 8.00, 'Asia/Seoul' => 9.00, 'Australia/Darwin' => 9.30, 'Australia/Canberra' => 10.00, 'Asia/Magadan' => 11.00, 'Pacific/Fiji' => 12.00, 'Pacific/Tongatapu' => 13.00);
$index = array_keys($zonelist, $_REQUEST['offset']);
$_SESSION['timezone'] = $index[0];
}
}
date_default_timezone_set($_SESSION['timezone']);
//rest of your code goes here
?>
Enkelt, bare bruke Javascript i getTimezoneOffset
funksjon slik:
-new Date().getTimezoneOffset()/60;
Prøv denne php-kode
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$json = file_get_contents("http://api.easyjquery.com/ips/?ip=".$ip."&full=true");
$json = json_decode($json,true);
$timezone = $json['LocalTimeZone'];
?>
Her er en robust Java løsning å bestemme tidssonen leseren er i.
>>> var timezone = jstz.determine();
>>> timezone.name();
"Europe/London"
Jeg har fortsatt ikke sett en detaljert svar her som får tidssonen. Du bør ikke trenger å geokode IP-adresse eller bruke PHP (lol) eller feil gjette fra en offset.
Først en tidssone er ikke bare en forskyvning fra GMT. Det er et område av landet der tidsbestemmelser er satt av lokale standarder. Noen land har sommertid, og vil slå på DST på forskjellige tider. Det er vanligvis viktig å få selve sonen, offset ikke bare strømmen.
Hvis du har tenkt å lagre denne tidssonen, for eksempel i brukerinnstillinger du ønsker sonen og ikke bare utlignet. For realtime konverteringer vil det ikke saken mye.
Nå, for å få tidssonen med javascript kan du bruke denne:
>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.
Men jeg fant det lettere å bare bruke denne robuste plugin som returnerer Olsen formatert tidssone:
For å legge inn tidssonen offset som en HTTP-header på AJAX forespørsler med jQuery
$.ajaxSetup({
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
}
});
Du kan også gjøre noe lignende for å få den faktiske tidssonen navn etter hjelp moment.tz.guess();
fra http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/
Ikke bruk IP-adresse til definitivt finne sted (og hense tidssone) - det er fordi med NAT, Fullmakter (stadig mer populært), og VPN, IP-adresser ikke nødvendigvis realistisk gjenspeile brukerens faktiske plassering, men stedet der serverne implementere disse protokollene bor.
I likhet med hvordan Area Codes ikke lenger er nyttig for å finne en telefonbruker, gitt populariteten til nummerportabilitet.
IP og andre teknikker vist ovenfor er nyttige for å foreslå en standard at brukeren kan justere / riktig.
Først forstå at tidssonen deteksjon i Javascript er ufullkommen. Du kan få den lokale tidssonen offset for en bestemt dato og klokkeslett ved hjelp getTimezoneOffset
av en forekomst av Date
objektet, men det er ikke helt det samme som en full IANA tidssone som America/Los_Angeles
.
Det er noen alternativer som kan fungere selv om:
De fleste moderne nettlesere støtter IANA tidssoner i sin gjennomføring av ECMAScript Internasjonalisering API , slik at du kan gjøre dette:
const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
Resultatet er en streng som inneholder IANA tidssonen innstilling av maskinen, hvor koden er i gang.
Støttede miljøer er listet opp i den internasjonale kompatibilitet tabellen . Utvid DateTimeFormat
delen, og se på funksjonen som heter resolvedOptions().timeZone defaults to the host environment
.
Hvis du trenger å støtte en bredere sett av miljøer, slik som eldre nettlesere, kan du bruke et bibliotek for å gjøre en kvalifisert gjetning på tidssonen. De virker ved første prøve Intl
API hvis det er tilgjengelig, og når det ikke er tilgjengelig, de avhøre getTimezoneOffset
funksjon av Date
objektet, for flere forskjellige tidspunkter, bruke resultatene til å velge en passende tidssonen fra en intern datasettet.
Både jsTimezoneDetect og øyeblikk-tidssone har denne funksjonaliteten.
// using jsTimeZoneDetect
var tzid = jstz.determine().name();
// using moment-timezone
var tzid = moment.tz.guess();
I begge tilfeller kan resultatet bare være tenkt som en gjetning. Gjette kan være riktig i mange tilfeller, men ikke alle av dem.
I tillegg disse bibliotekene må oppdateres jevnlig for å motvirke det faktum at mange eldre Javascript implementeringer er bare klar over den nåværende sommertid regel for sine lokale tidssone. Flere detaljer om det her.
Til syvende og sist er en bedre tilnærming å faktisk spørre brukeren om deres tidssone. Gi en innstilling om at de kan endre. Du kan bruke en av de ovennevnte alternativer å velge en standardinnstilling, men ikke gjør det umulig å avvike fra den i din app.
Det er også helt annen tilnærming til ikke å stole på tidssoneinnstillingen på brukerens datamaskin i det hele tatt. I stedet, hvis du kan samle lengde- og breddegrader, kan du løse de til en tidssone ved hjelp av en av disse metodene . Dette fungerer godt på mobile enheter.
Ett mulig alternativ er å bruke Date
header-feltet, som er definert i RFC 7231 og er ment å omfatte tidssonen. Selvfølgelig er det ikke garantert at verdien er virkelig kundens tidssone, men det kan være et gunstig utgangspunkt.
Enkelt med JS
og PHP
:
Selv om brukeren kan rote med sin interne klokke og / eller tidssone, den beste måten jeg funnet så langt, for å få offset, forblir new Date().getTimezoneOffset();
. Sin ikke-invasiv, ikke gi hodesmerter og eliminerer behovet for å stole på tredjeparter.
Si jeg har en tabell users
som inneholder et felt date_created int(13)
, for lagring av UNIX-tidsstempler;
Forutsatt en klient creates a new account
, er data mottatt av post
, og jeg trenger å insert/update
den date_created column
med kundens unix tidsstempel, ikke serverens.
Siden timezoneOffset er nødvendig på tidspunktet for innsatsen / oppdateringen, er det gått som en ekstra $ _POST element når kunden sender inn skjemaet, og dermed eliminere behovet for å lagre det i økter og / eller informasjonskapsler, og ingen ekstra server treffer heller.
var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;
Si serveren mottar tzo
som $_POST['tzo']
;
$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);
Sett / oppdatering date_created=$user_timestamp
.
Når hente DATE_CREATED, kan du konvertere tidsstempelet som så:
$date_created = //get from db
$created = date("F j, Y, g:i a",$date_created);//return it to the user or whatever
Nå kan dette eksemplet passer ens behov, når det kommer til å sette inn et first
tidsstempel ... Når det kommer til en ekstra tidsstempel, eller bord, vil u kanskje vurdere å sette inn TZO verdien i brukertabellen for fremtidig referanse, eller sette den som økt eller som en cookie.
PS Men hva hvis brukeren reiser og bytter tidssoner. Logger i på GMT + 4, reiser raskt til GMT-en og logger inn igjen. Siste pålogging vil være i fremtiden.
Jeg tror ... vi tenker for mye.
du kunne gjøre det på klient med øyeblikk tidssone og sender verdien til serveren; sample bruk:
> moment.tz.guess()
"America/Asuncion"
Får en gyldig TZ Database tidssone navn i PHP er en to trinns prosess:
1) Med Javascript, får tidssone offset i minutter gjennom getTimezoneOffset
. Denne forskyvningen vil være positivt hvis den lokale tidssonen står bak UTC og negativ hvis det er fremover. Så du må legge til en motsatt fortegn til offset.
var timezone_offset_minutes = new Date().getTimezoneOffset();
timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
Pass dette utlignet til PHP.
2) I PHP konvertere dette oppveie inn et gyldig tidssone navn med timezone_name_from_abbr funksjon.
// Just an example.
$timezone_offset_minutes = -360; // $_GET['timezone_offset_minutes']
// Convert minutes to seconds
$timezone_name = timezone_name_from_abbr("", $timezone_offset_minutes*60, false);
// America/Chicago
echo $timezone_name;
Jeg har skrevet et blogginnlegg på det: http://usefulangle.com/post/31/detect-user-browser-timezone-name-in-php Den inneholder en demo også.