Vra

Is daar 'n standaard manier vir 'n webbediener om 'n gebruiker se tydsone binne 'n webblad te kan bepaal?

Miskien van 'n HTTP-kopskrif of deel van die user-agent string?

Geen korrekte oplossing nie

Ander wenke

-new Date().getTimezoneOffset()/60;

Die metode getTimezoneOffset() sal jou tyd van GMT aftrek en die aantal minute terugstuur.So as jy in GMT-8 woon, sal dit 480 teruggee.

Om dit in ure te plaas, deel deur 60.Let ook op dat die teken die teenoorgestelde is van wat jy nodig het - dit is om GMT se afwyking vanaf jou tydsone te bereken, nie jou tydsone se afwyking vanaf GMT nie.Om dit reg te stel, vermenigvuldig eenvoudig met -1.

Let ook daarop w3skool sê:

Die teruggestuurde waarde is nie 'n konstante nie, as gevolg van die gebruik van dagligbesparingstyd.

Die gewildste (==standaard?) manier om die tydsone te bepaal wat ek nog gesien het, is eenvoudig vra die gebruikers self. As jou webwerf intekening vereis, kan dit in die gebruikers se profieldata gestoor word.Vir anongebruikers kan die datums as UTC of GMT of so iets vertoon word.

Ek probeer nie om 'n slim aleck te wees nie.Dit is net dat sommige probleme soms fyner oplossings het buite enige programmeringskonteks.

Daar is geen HTTP-opskrifte wat die kliënt se tydsone tot dusver sal rapporteer nie, alhoewel daar voorgestel is om dit by die HTTP-spesifikasie in te sluit.

As dit ek was, sou ek waarskynlik probeer om die tydsone te haal met JavaScript aan die kliënt en dit dan aan die bediener voor te lê met Ajax of iets.

JavaScript is die maklikste manier om die kliënt se plaaslike tyd te kry.Ek sou voorstel om 'n XMLHttpRequest om die plaaslike tyd terug te stuur, en as dit misluk, val terug na die tydsone wat op grond van hul IP-adres bespeur is.

Wat geoligging betref, het ek gebruik MaxMind GeoIP op verskeie projekte en dit werk goed, alhoewel ek nie seker is of hulle tydsonedata verskaf nie.Dit is 'n diens waarvoor jy betaal en hulle verskaf maandelikse opdaterings aan jou databasis.Hulle verskaf omhulsels in verskeie webtale.

Hier is 'n robuuste JavaScript-oplossing om die tydsone waarin die blaaier is te bepaal.

>>> var timezone = jstz.determine();
>>> timezone.name(); 
"Europe/London"

https://bitbucket.org/pellpim/jstimezonedetect

Hier is 'n meer volledige manier.

  1. Kry die tydsone-kompensasie vir die gebruiker
  2. Toets sommige dae op dagligbesparingsgrense om te bepaal of hulle in 'n sone is wat dagligbesparing gebruik.

'n Uittreksel is hieronder:

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

Kry TZ en DST by JS (via Way Back Machine)

Eerstens, verstaan ​​​​dat tydsone-opsporing in JavaScript onvolmaak is.Jy kan die plaaslike kry tydsone verreken vir 'n spesifieke datum en tyd gebruik getTimezoneOffset op 'n geval van die Date voorwerp, maar dit is nie heeltemal dieselfde as 'n vol nie IANA tydsone hou van America/Los_Angeles.

Daar is egter 'n paar opsies wat kan werk:

  • Die meeste moderne blaaiers ondersteun IANA tydsones in hul implementering van die ECMAScript Internasionalisering API, sodat jy dit kan doen:

    const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
    

    Die resultaat is 'n string wat die IANA-tydsone-instelling van die rekenaar bevat waar die kode loop.

    Ondersteunde omgewings word gelys in die Intl-versoenbaarheidstabel.Brei die uit DateTimeFormat afdeling, en kyk na die kenmerk genoem resolvedOptions().timeZone defaults to the host environment.

    • Sommige biblioteke, soos Luxon gebruik hierdie API om die tydsone te bepaal deur funksies soos luxon.Settings.defaultZoneName.
  • As jy 'n wyer stel omgewings moet ondersteun, soos ouer webblaaiers, kan jy 'n biblioteek gebruik om 'n opgevoede raai by die tydsone.Hulle werk deur eers die te probeer Intl API as dit beskikbaar is, en wanneer dit nie beskikbaar is nie, ondervra hulle die getTimezoneOffset funksie van die Date voorwerp, vir verskeie verskillende tye in tyd, deur die resultate te gebruik om 'n gepaste tydsone uit 'n interne datastel te kies.

    Albei jsTimezoneDetect en oomblik-tydsone beskik oor hierdie funksie.

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();
    

    In beide gevalle kan die resultaat slegs as 'n raaiskoot beskou word.Die raaiskoot kan in baie gevalle korrek wees, maar nie almal nie.

    Daarbenewens moet hierdie biblioteke periodiek bygewerk word om die feit teen te werk dat baie ouer JavaScript-implementerings slegs bewus is van die huidige dagligbesparingstydreël vir hul plaaslike tydsone. Meer besonderhede daaroor hier.

Uiteindelik is 'n beter benadering om u gebruiker vir hul tydsone te vra.Verskaf 'n instelling wat hulle kan verander.Jy kan een van die bogenoemde opsies gebruik om 'n verstek instelling, maar moenie dit onmoontlik maak om daarvan in jou toepassing af te wyk nie.

Daar is ook die heel ander benadering van nie staatmaak op die tydsone instelling van die gebruiker se rekenaar enigsins.In plaas daarvan, as jy breedte- en lengtegraadkoördinate kan versamel, kan jy dit na 'n tydsone herlei deur een van hierdie metodes.Dit werk goed op mobiele toestelle.

Deur Unkwntech se benadering te gebruik, het ek 'n funksie geskryf met jQuery en PHP.Dit is getoets en werk!

Op die PHP-bladsy waar jy die tydsone as 'n veranderlike wil hê, het hierdie stukkie kode iewers naby die bokant van die bladsy:

<?php
    session_start();
    $timezone = $_SESSION['time'];
?>

Dit sal die sessieveranderlike "tyd" lees, wat ons nou gaan skep.

Op dieselfde bladsy, in die <head>, moet jy eerstens jQuery insluit:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

Plak dit ook in die <head>, onder die jQuery:

<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://example.org/timezone.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

Jy het dalk opgemerk of nie, maar jy moet die URL na jou werklike domein verander.

Een laaste ding.Jy wonder waarskynlik wat die heck timezone.php is.Wel, dit is eenvoudig dit:(skep 'n nuwe lêer genaamd tydsone.php en wys daarna met die bogenoemde URL)

<?php
    session_start();
    $_SESSION['time'] = $_GET['time'];
?>

As dit reg werk, sal dit eers die bladsy laai, die JavaScript uitvoer en die bladsy herlaai.Jy sal dan die $tydsone-veranderlike kan lees en dit tot jou plesier kan gebruik!Dit gee die huidige UTC/GMT-tydsone-afset (GMT -7) of watter tydsone jy ook al is.

Ek het nog nie 'n gedetailleerde antwoord hier gesien wat die tydsone kry nie.Jy hoef nie te geokodeer volgens IP-adres of PHP (lol) te gebruik of verkeerdelik te raai vanaf 'n verrekening nie.

Eerstens is 'n tydsone nie net 'n verrekening van GMT nie.Dit is 'n grondgebied waarin die tydreëls volgens plaaslike standaarde bepaal word.Sommige lande het dagligbesparing en sal DST op verskillende tye aanskakel.Dit is gewoonlik belangrik om die werklike sone te kry, nie net die huidige offset nie.

As jy van plan is om hierdie tydsone te stoor, byvoorbeeld in gebruikervoorkeure, wil jy die sone hê en nie net die afwyking nie.Vir intydse omskakelings sal dit nie veel saak maak nie.

Nou, om die tydsone met javascript te kry, kan jy dit gebruik:

>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.

Ek het dit egter makliker gevind om eenvoudig hierdie robuuste inprop te gebruik wat die Olsen-geformateerde tydsone terugstuur:

https://github.com/scottwater/jquery.detect_timezone

Om die tydsone-offset as 'n HTTP-opskrif op AJAX-versoeke in te dien met jQuery

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
    }
});

Jy kan ook iets soortgelyks doen om die werklike tydsonenaam te kry deur te gebruik moment.tz.guess(); van http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

Met die PHP date funksie kry jy die datum tyd van bediener waarop die webwerf geleë is.Die enigste manier om die gebruiker tyd te kry, is om JavaScript te gebruik.

Maar ek stel voor dat u, as u webwerf registrasie vereis het, die beste manier is om die gebruiker te vra terwyl hy registrasie as 'n verpligte veld moet hê.U kan verskillende tydsones in die registerbladsy lys en dit in die databasis stoor.Hierna, as die gebruiker by die webwerf aanmeld, kan u die verstektydsone vir daardie sessie instel volgens die gebruikers se gekose tydsone.

U kan enige spesifieke tydsone instel deur die PHP-funksie te gebruik date_default_timezone_set.Dit stel die gespesifiseerde tydsone vir gebruikers.

Basies gaan die gebruikers se tydsone na die kliëntkant, so ons moet JavaScript hiervoor gebruik.

Hieronder is die skrif om gebruikers se tydsone te kry met PHP en 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();
?>

Maar volgens my standpunt is dit beter om aan die gebruikers te vra of registrasie verpligtend is in jou projek.

Maklik, gebruik net die JavaScript getTimezoneOffset funksioneer so:

-new Date().getTimezoneOffset()/60;

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

Verskaf eenvoudig jou tye in Unix-tydstempelformaat aan hierdie funksie;JavaScript ken reeds die tydsone van die gebruiker.

Soos hierdie:

PHP:

echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';

Dit sal altyd die tye korrek wys gebaseer op die tydsone wat die persoon op sy/haar rekenaarklok gestel het.Dit is nie nodig om iets aan enigiemand te vra en dit op plekke te stoor nie, goddank!

Dit lyk of die magie alles in is

visitortime.getTimezoneOffset()

Dis cool, ek het nie daarvan geweet nie.Werk dit in Internet Explorer, ens.?Van daar af behoort jy JavaScript vir Ajax te kan gebruik, koekies kan stel, wat ook al.Ek sou seker self die koekie-roete gaan.

Jy sal egter die gebruiker moet toelaat om dit te verander.Ons het 'n ruk gelede probeer om geoligging (via maxmind) te gebruik om dit te doen, en dit was redelik dikwels verkeerd - genoeg om dit nie die moeite werd te maak nie, so ons laat die gebruiker dit net in hul profiel stel, en wys 'n kennisgewing aan gebruikers wat het hulle nog nie gestel nie.

Moenie die IP-adres gebruik om definitief ligging (en dus tydsone) te bepaal nie - dit is omdat met NAT, gevolmagtigdes (al hoe gewilder) en VPN's, IP-adresse nie noodwendig die gebruiker se werklike ligging realisties weerspieël nie, maar die ligging waar die bedieners wat daardie protokolle implementeer, woon.

Soortgelyk aan hoe Amerikaanse areakodes nie meer nuttig is om 'n telefoongebruiker op te spoor nie, gegewe die gewildheid van nommeroordraagbaarheid.

IP-adres en ander tegnieke wat hierbo getoon word, is nuttig vir wat 'n verstek voorstel dat die gebruiker kan aanpas/korrigeer.

As jy toevallig gebruik OpenID vir verifikasie, Eenvoudige registrasie-uitbreiding sal die probleem vir geverifieerde gebruikers oplos (Jy sal van tz na numeries moet omskakel).

Nog 'n opsie sou wees om die tydsone af te lei uit die gebruikeragent se landvoorkeur.Dit is 'n ietwat kru metode (sal nie vir en-US werk nie), maar maak 'n goeie benadering.

Hier is 'n artikel (met bronkode) wat verduidelik hoe om gelokaliseerde tyd in 'n ASP.NET (VB.NET, C#) toepassing te bepaal en te gebruik:

Dis omtrent tyd

Kortom, die beskryf benadering maak staat op die JavaScript getTimezoneOffset funksie, wat die waarde terugstuur wat in die sessiekoekie gestoor is en deur kode-agter gebruik word om tydwaardes tussen GMT en plaaslike tyd aan te pas.Die lekker ding is dat die gebruiker nie die tydsone hoef te spesifiseer nie (die kode doen dit outomaties).Daar is meer betrokke (dit is hoekom ek na die artikel skakel), maar die verskafde kode maak dit baie maklik om te gebruik.Ek vermoed dat jy die logika na PHP en ander tale kan omskakel (solank jy ASP.NET verstaan).

Dit is eenvoudig met JavaScript en PHP:

Selfs al kan die gebruiker met sy/haar interne horlosie en/of tydsone mors, bly die beste manier wat ek tot dusver gevind het, om die verrekening te kry. new Date().getTimezoneOffset();.Dit is nie-indringend, gee nie hoofpyn nie en skakel die behoefte uit om op derde partye staat te maak.

Sê ek het 'n tafel, users, wat 'n veld bevat date_created int(13), vir die stoor van Unix-tydstempels;

Aanvaar 'n kliënt creates a new account, word data ontvang deur post, en ek moet insert/update die date_created column met die kliënt se Unix-tydstempel, nie die bediener s'n nie.

Aangesien die tydsoneOffset nodig is ten tyde van invoeging/opdatering, word dit as 'n ekstra $_POST-element deurgegee wanneer die kliënt die vorm indien, wat die behoefte uitskakel om dit in sessies en/of koekies te stoor, en ook geen bykomende bedienertreffers nie.

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;

Sê die bediener ontvang tzo as $_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);

Voeg in / werk op date_created=$user_timestamp.

Wanneer jy die date_created herwin, kan jy die tydstempel soos volg omskakel:

$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever

Nou, hierdie voorbeeld pas dalk by 'n mens se behoeftes, wanneer dit kom by die invoeging van 'n first tydstempel...Wanneer dit kom by 'n bykomende tydstempel, of tabel, sal jy dalk wil oorweeg om die tzo-waarde in die gebruikerstabel in te voeg vir toekomstige verwysing, of dit as sessie of as 'n koekie te stel.

P.S.MAAR wat as die gebruiker reis en tydsones verander.Meld aan by GMT+4, reis vinnig na GMT-1 en meld weer aan.Laaste aanmelding sal in die toekoms wees.

Ek dink...ons dink te veel.

Jy kan dit op die kliënt doen met oomblik-tydsone en stuur die waarde na bediener;voorbeeld gebruik:

> moment.tz.guess()
"America/Asuncion"

'n Eenvoudige manier om dit te doen is deur die volgende te gebruik:

new Date().getTimezoneOffset();

Om 'n geldige TZ-databasis-tydsonenaam in PHP te kry, is 'n tweestap-proses:

  1. Met JavaScript, kry tydsone verreken in minute deur getTimezoneOffset.Hierdie verrekening sal positief wees as die plaaslike tydsone agter UTC is en negatief as dit voor is.So jy moet 'n teenoorgestelde teken by die offset voeg.

    var timezone_offset_minutes = new Date().getTimezoneOffset();
    timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
    

    Gee hierdie verrekening deur aan PHP.

  2. In PHP omskep hierdie offset in 'n geldige tydsone naam met tydsone_naam_van_afkort funksie.

    // 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;</code></pre>
    

Ek het 'n blogpos daaroor geskryf: Hoe om gebruikerstydsone in PHP op te spoor.Dit bevat ook 'n demo.

Een moontlike opsie is om die Date opskrifveld, wat gedefinieer word in RFC 7231 en is veronderstel om die tydsone in te sluit.Dit is natuurlik nie gewaarborg dat die waarde werklik die kliënt se tydsone is nie, maar dit kan 'n gerieflike beginpunt wees.

Hier is hoe ek dit doen.Dit sal die PHP verstek tydsone stel na die gebruiker se plaaslike tydsone.Plak net die volgende bo-aan al jou bladsye:

<?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
?>

Probeer hierdie 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'];
?>
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top