Bestimmen Sie die Zeitzone eines Benutzers

610

Gibt es eine Standardmethode für einen Webserver, um die Zeitzone eines Benutzers innerhalb einer Webseite zu bestimmen?

Vielleicht aus einem HTTP-Header oder einem Teil der user-agentZeichenfolge?

Kevin Dente
quelle
6
Fragen Sie den Benutzer. Wenn Sie die Zeitzone vom Computer des Benutzers erhalten und sie falsch eingestellt ist, was dann?
Rob Williams
40
Dann ist es dem Benutzer wahrscheinlich egal?
Agnoster
2
Leider ermöglichen die Antworten auf diese Frage auch Benutzerprofile und Geofencing.
William Entriken
1
Warum müssen Sie die Zeitzone des Benutzers kennen?
Braiam

Antworten:

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

Die Methode getTimezoneOffset()subtrahiert Ihre Zeit von GMT und gibt die Anzahl der Minuten zurück. Wenn Sie also in GMT-8 leben, wird 480 zurückgegeben.

Um dies in Stunden zu fassen, dividieren Sie durch 60. Beachten Sie auch, dass das Vorzeichen das Gegenteil von dem ist, was Sie benötigen - es berechnet den Versatz von GMT von Ihrer Zeitzone, nicht den Versatz Ihrer Zeitzone von GMT. Um dies zu beheben, multiplizieren Sie einfach mit -1.

Beachten Sie auch, dass w3school sagt:

Der zurückgegebene Wert ist aufgrund der Verwendung der Sommerzeit keine Konstante.

JD Isaacks
quelle
5
Was ist mit Benutzern, die Handys mit Browsern ohne Javascript-Unterstützung verwenden? Ich mag die Frage, der Benutzer fragt nach HTTP-Headern, Benutzeragenten ... Gibt es eine Möglichkeit, diese Arbeitsserverseite so genau wie möglich zu gestalten?
Nischal
18
Dies funktioniert nicht immer für die Sommerzeit. Get Timezone Offset macht genau das, was es sagt. Es ist der Offset. Eine Zeitzone ist eigentlich ein geografisches Gebiet. Dies funktioniert nicht für die Sommerzeit, da Sie nicht wissen, in welcher Hemisphäre der Benutzer lebt oder ob sein Land überhaupt Sommerzeit hat. Warum nicht stattdessen verwenden:>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
Keyo
20
Ich möchte mich mit Keyo unterscheiden. Die Definition von getTimezoneOffset () (gemäß dem ECMA-Standard ecma-international.org/ecma-262/5.1/#sec-15.9.5.26 ) lautet "Gibt die Differenz zwischen Ortszeit und UTC-Zeit in Minuten zurück." - Mit anderen Worten, es sollte die Sommerzeit berücksichtigt werden. In der Dokumentation von Mozilla heißt es: "Die Sommerzeit verhindert, dass dieser Wert auch für ein bestimmtes Gebietsschema konstant bleibt."
Xgretsch
11
@xgretsch: Ermittelt den aktuellen Offset des Benutzers von GMT. Dies ist in Ordnung, wenn Sie eine andere Uhrzeit am selben Tag angeben (es sei denn, das aktuelle Datum ist ein Umstellungsdatum, bei dem es falsch sein könnte). Es gibt jedoch viele Zeitzonen, die den gleichen Versatz von GMT haben, und sie haben möglicherweise unterschiedliche Umstellungsdaten oder verwenden keine Sommerzeit.
Mike Dimmick
12
Eine Sache, die hier zu beachten ist; Einige Orte (wie Neufundland in Kanada) haben Zeitzonen, die um eine halbe Stunde verschoben sind. Nach dem Teilen durch 60 ist Ihre Antwort möglicherweise keine Ganzzahl.
Jason Walton
193

Die beliebteste (== Standard?) Methode zur Bestimmung der Zeitzone, die ich gesehen habe, besteht darin, einfach die Benutzer selbst zu fragen. Wenn für Ihre Website ein Abonnement erforderlich ist, kann dieses in den Profildaten der Benutzer gespeichert werden. Für anon Benutzer können die Daten als UTC oder GMT oder ähnliches angezeigt werden.

Ich versuche nicht, ein kluger Kerl zu sein. Es ist nur so, dass manchmal einige Probleme außerhalb eines Programmierkontexts feinere Lösungen haben.

Ishmaeel
quelle
5
Was ist, wenn ein Benutzer eine .ics-Datei herunterlädt, deren Startzeit für seinen Standort spezifisch sein sollte (z. B. 9 bis 11 Uhr im ganzen Land)? Sie sollten nicht sagen müssen, was ihre Zeitzone imo ist.
Marcy Sutton
33
@Ishmaeel: aber Benutzer reisen international und sollten nicht jedes Mal ihre Zeitzone angeben müssen, wenn sie sich von einer nicht einheimischen Zeitzone aus anmelden
Rajat Gupta
10
Dies beantwortet nicht die Frage, was eindeutig impliziert, dass er nach einer technologischen Lösung sucht.
G-Wiz
5
@gWiz OP fragt nach einer Standardlösung. Das ist ziemlich normal.
Simon Bergot
4
Die beste Lösung wäre wahrscheinlich eine Kombination aus der Befragung des Benutzers (z. B. Bereitstellung einer Dropdown-Liste für die Zeitzone oben in einem Bericht), während die Dropdown-Auswahl standardmäßig auf eine vom GPS festgelegte Zeitzone eingestellt wird, wenn sich der Benutzer auf einem Mobiltelefon befindet Gerät, das Standortinformationen bereitstellt und ansonsten standardmäßig UTC verwendet.
Triynko
132

Bisher gibt es keine HTTP-Header, die die Zeitzone des Clients melden, obwohl vorgeschlagen wurde, sie in die HTTP-Spezifikation aufzunehmen.

Wenn ich es wäre, würde ich wahrscheinlich versuchen, die Zeitzone mit clientseitigem JavaScript abzurufen und sie dann mit Ajax oder etwas anderem an den Server zu senden.

Mads Kristiansen
quelle
16
Seltsamerweise ist dies die einzig richtige Antwort auf die Frage, wie man es serverseitig macht. Ich vermute, der Grund, warum es andere Antworten mit mehr Stimmen gibt, ist, dass Sie, sobald Sie erkennen, dass Sie dies auf der Clientseite tun müssen, am Ende die anderen Antworten verwenden. Aber meiner Meinung nach sollte jeder, der eine andere Antwort positiv bewertet, auch diese positiv bewerten.
TTT
Ich glaube, die beste Methode besteht darin, die möglichen Zeitzonen mithilfe des Geo-IP-Standorts zu sortieren und standardmäßig die erste auszuwählen, die dem Zeitversatz des Benutzeragenten (nahe) entspricht (JavaScript erforderlich). Auch danach müssen Sie eine Möglichkeit bereitstellen, die Zeitzone zu korrigieren, nachdem selbst diese Methode die falsche ausgewählt hat.
Mikko Rantalainen
@MikkoRantalainen Vorsicht bei der Verwendung von Proxys durch, da sie sich nicht immer in den Headern bewerben.
Matthieu
@Matthieu gibt es heutzutage eine bessere Antwort: stackoverflow.com/a/11836123/334451
Mikko Rantalainen
2
Dies ist buchstäblich die einzige Antwort, die sich tatsächlich mit der gestellten Frage befasst.
lscoughlin
54

JavaScript ist der einfachste Weg, um die Ortszeit des Clients abzurufen. Ich würde vorschlagen, eine XMLHttpRequest zu verwenden, um die Ortszeit zurückzusenden. Wenn dies fehlschlägt, greifen Sie auf die Zeitzone zurück, die anhand ihrer IP-Adresse ermittelt wurde.

In Bezug auf die Geolokalisierung habe ich MaxMind GeoIP in mehreren Projekten verwendet und es funktioniert gut, obwohl ich nicht sicher bin, ob sie Zeitzonendaten liefern. Es ist ein Service, für den Sie bezahlen und der monatliche Aktualisierungen Ihrer Datenbank bereitstellt. Sie bieten Wrapper in mehreren Web-Sprachen.

pix0r
quelle
Ich habe diese Antwort abgelehnt, weil der Längen- und Breitengrad von Datenbanken wie GeoIP (für die ab sofort eine kostenlose Version verfügbar ist) mit Datenbanken kombiniert werden kann, die eine solche Koordinate in eine Zeitzone konvertieren. Ich denke, GeoNames hat eine letztere solche Datenbank.
Peter O.
Die aktuellen Versionen (sowohl kostenlos als auch kostenpflichtig) der MaxMind GeoIP-Datenbanken / APIs liefern tatsächlich Zeitzoneninformationen (für meine Zeitzone wird "Europa / London" zurückgegeben). Ich kann mich nicht erinnern, ob die alte Version ihres GeoIP-Systems tat das gleiche, aber es funktioniert jetzt sehr gut! Die MaxMind-Felder heißen "time_zone", "time_zone_name".
Matthew Slyman
51

Verstehen Sie zunächst, dass die Zeitzonenerkennung in JavaScript nicht perfekt ist. Sie können die lokal bekommen Zeitzonen - Offset für ein bestimmtes Datum und die Uhrzeit mit getTimezoneOffsetauf einer Instanz des DateObjekts, aber das ist nicht ganz das gleiche wie eine Voll IANA Zeitzone wie America/Los_Angeles.

Es gibt jedoch einige Optionen, die funktionieren können:

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

Das Ergebnis ist eine Zeichenfolge, die die IANA-Zeitzoneneinstellung des Computers enthält, auf dem der Code ausgeführt wird.

Unterstützte Umgebungen sind in der Intl-Kompatibilitätstabelle aufgeführt . Erweitern Sie den DateTimeFormatAbschnitt und sehen Sie sich die genannte Funktion an resolvedOptions().timeZone defaults to the host environment.

  • Einige Bibliotheken wie Luxon verwenden diese API, um die Zeitzone durch Funktionen wie zu bestimmen luxon.Settings.defaultZoneName.

    • Wenn Sie eine größere Anzahl von Umgebungen unterstützen müssen, z. B. ältere Webbrowser, können Sie mithilfe einer Bibliothek eine fundierte Schätzung der Zeitzone vornehmen . Sie testen zunächst die IntlAPI, wenn sie verfügbar ist, und wenn sie nicht verfügbar ist, fragen sie die getTimezoneOffsetFunktion des DateObjekts zu verschiedenen Zeitpunkten ab und verwenden die Ergebnisse, um eine geeignete Zeitzone aus einem internen Datensatz auszuwählen.

    Sowohl jsTimezoneDetect als auch moment-timezone verfügen über diese Funktionalität.

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

    In beiden Fällen kann das Ergebnis nur als Vermutung betrachtet werden. Die Vermutung mag in vielen Fällen richtig sein, aber nicht in allen.

    Darüber hinaus müssen diese Bibliotheken regelmäßig aktualisiert werden, um der Tatsache entgegenzuwirken, dass viele ältere JavaScript-Implementierungen nur die aktuelle Sommerzeitregel für ihre lokale Zeitzone kennen. Mehr dazu hier.

Letztendlich ist es ein besserer Ansatz, Ihren Benutzer tatsächlich nach seiner Zeitzone zu fragen. Geben Sie eine Einstellung an, die sie ändern können. Sie können eine der oben genannten Optionen verwenden, um eine Standardeinstellung auszuwählen , aber machen Sie es nicht unmöglich, in Ihrer App davon abzuweichen.

Es gibt auch einen völlig anderen Ansatz, sich überhaupt nicht auf die Zeitzoneneinstellung des Computers des Benutzers zu verlassen. Wenn Sie stattdessen Längen- und Breitengradkoordinaten erfassen können, können Sie diese mit einer dieser Methoden in eine Zeitzone auflösen . Dies funktioniert gut auf mobilen Geräten.

Matt Johnson-Pint
quelle
Die Verwendung des geografischen Standorts des Benutzers (dh seines Gebietsschemas) zum Ableiten der Zeitzone ist ebenfalls fehlerhaft. Benutzer möchten möglicherweise eine bestimmte Zeitzone auf ihrem Gerät verwenden, die nicht die lokale Zeitzone ist, obwohl sie möglicherweise dieselbe Zeit anzeigen (oder nicht). Beispielsweise verlassen Reisende ihre Geräte häufig mit der Zeitzone, die auf ihren gewohnten Ort eingestellt ist, und erwarten nicht, dass Datum und Uhrzeit einen anderen Versatz verwenden, ohne dass dies empfohlen wird. Ich könnte aus persönlicher Erfahrung hier sprechen ... ;-)
RobG
Ich kann nicht sagen, ob du mich trollst, Rob. ;) Aber keiner dieser Ansätze verwendet sein Gebietsschema, sondern die Einstellung auf dem Gerät, stimmt also mit Ihrem Punkt überein. (Nur der im letzten Absatz erwähnte alternative Ansatz würde den aktuellen Standort verwenden.)
Matt Johnson-Pint
Mit einem Terminologie-Hinweis: "Gebietsschema" ist nachdrücklich nicht der geografische Standort des Benutzers. "Gebietsschema" ist eine Gruppe von Einstellungen wie Sprache, Zahlenformat, Kalender usw. Das Gebietsschema de_DE gibt beispielsweise Deutsch als Standardsprache, den Euro als Standardwährung, Kommas als Dezimaltrennzeichen, Punkte als Tausendertrennzeichen und Gregorianisch an als Kalender. Siehe developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
azernik
49

Hier ist eine robuste JavaScript-Lösung, um die Zeitzone zu bestimmen, in der sich der Browser befindet.

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

https://bitbucket.org/pellepim/jstimezonedetect

Anhang 1: Jetzt befindet sich dieses Projekt auf GitHub: https://github.com/pellepim/jstimezonedetect

Adam
quelle
14
Von Antworten nur auf Links wird abgeraten, da die Antwort nicht mehr nützlich ist, wenn der Link verschwindet. und weil die Leser, ohne dem Link zu folgen, nicht wissen, ob er eine gute Antwort gibt. In diesem Fall könnten Sie klarstellen, dass es sich um eine Bibliothek eines Drittanbieters handelt, die einen datenbankbasierten Ansatz zur Identifizierung verfolgt, und möglicherweise einige der Funktionsprinzipien erläutern.
IMSoP
1
Diese! Dies ist der richtige Weg. Einfache Bibliothek, behandelt die Sommerzeit richtig. Andere Antworten sind voller WTF und viele machen keine Sommerzeit.
Dirbaio
1
Diese Bibliothek ist sehr schlau. Es funktioniert, indem der aktuelle Versatz nach UTC abgefragt und dann die Objektzeit des JavaScript-Datums angepasst wird, indem Sekunden hinzugefügt oder entfernt werden, bis sich der Versatz nach UTC ändert. Mit dieser Methode ermittelt diese Bibliothek genügend DST-Änderungen, um die Zeitzone eindeutig zu identifizieren. Ich denke, die Bibliothek könnte eine noch bessere Leistung erzielen, wenn sie eine binäre Suche anstelle einer linearen Suche durchführen würde. Der Rückgabewert ist ein IANA-Zoneninformationsschlüssel (auch bekannt als Olson-Zeitzonendatenbank).
Mikko Rantalainen
3
Diese Bibliothek wird nicht mehr benötigt. Moderne Browser unterstützen die Intl-API, die die IANA-Zeitzonenzeichenfolge zurückgibt. Siehe diese Antwort .
Dan Dascalescu
42

Hier ist ein vollständigerer Weg.

  1. Holen Sie sich den Zeitzonenversatz für den Benutzer
  2. Testen Sie einige Tage an den Sommerzeitgrenzen, um festzustellen, ob sie sich in einer Zone befinden, in der die Sommerzeit verwendet wird.

Ein Auszug ist unten:

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

TZ und DST von JS erhalten (über Way Back Machine)

Joseph Lust
quelle
Das hat bei mir funktioniert! Lesen Sie die Kommentare unter dem Blog-Beitrag, um einige Aktualisierungen des Codes zu erhalten.
Arlomedia
Dies gibt immer noch nur den Standardoffset für die Zeitzone zurück, z. B. +02: 00. Sie erhalten nicht genügend Informationen, um die Zeitzone des Benutzers zu bestimmen , z. B. Africa/Johannesburgoder Europe/Istanbul. Siehe das Zeitzonen-Tag-Wiki .
Matt Johnson-Pint
32

Mit dem Ansatz von Unkwntech habe ich eine Funktion mit jQuery und PHP geschrieben. Dies ist getestet und funktioniert!

Auf der PHP-Seite, auf der Sie die Zeitzone als Variable haben möchten, befindet sich dieser Codeausschnitt irgendwo oben auf der Seite:

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

Dies liest die Sitzungsvariable "Zeit", die wir jetzt erstellen werden.

Auf derselben Seite müssen Sie im <head> zunächst jQuery einschließen:

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

Fügen Sie auch im <head> unterhalb der jQuery Folgendes ein:

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

Möglicherweise haben Sie es bemerkt oder nicht, aber Sie müssen die URL in Ihre tatsächliche Domain ändern.

Eine letzte Sache. Sie fragen sich wahrscheinlich, was zum Teufel timezone.php ist. Nun, es ist einfach so: (Erstellen Sie eine neue Datei namens timezone.php und zeigen Sie mit der obigen URL darauf)

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

Wenn dies korrekt funktioniert, wird zuerst die Seite geladen, das JavaScript ausgeführt und die Seite neu geladen. Sie können dann die Variable $ timezone lesen und zu Ihrem Vergnügen verwenden! Es gibt den aktuellen UTC / GMT-Zeitzonenversatz (GMT -7) oder die Zeitzone zurück, in der Sie sich befinden.

Westy92
quelle
Ich mag das, aber ich könnte etwas haben, das die aktuelle $ _SESSION ['Zeit'] überprüft und nur das Javascript zum Neuladen bringt, wenn es anders ist
Christopher Chase
1
Es ist wahrscheinlich einfacher, ein Cookie als eine Sitzung zu verwenden, um dies zu transportieren, da das Sperren und unserialisieren der PHP-Sitzung zu Verlangsamungen in Ihrer App führen kann. Für maximale Effizienz können Sie den Wert in die Sitzung kopieren und das Cookie löschen, damit es bei nachfolgenden Anforderungen nicht gesendet wird.
IMSoP
25

Übermitteln des Zeitzonenversatzes als HTTP-Header bei AJAX-Anforderungen mit jQuery

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

Sie können auch etwas ähnliches tun , um die tatsächlichen Zeitzonennamen , indem Sie erhalten moment.tz.guess();von http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

Philfreo
quelle
1
Dies gibt nur den aktuellen Zeitzonenversatz zurück - nicht die Zeitzone . Siehe das Zeitzonen-Tag-Wiki .
Matt Johnson-Pint
Bearbeitet, um Informationen darüber zu erhalten, wie Sie dasselbe für den Zeitzonennamen tun können.
Philfreo
24

Ich habe hier noch keine detaillierte Antwort gesehen, die die Zeitzone erhält. Sie sollten nicht nach IP-Adresse geocodieren oder PHP (lol) verwenden oder falsch von einem Offset raten müssen.

Erstens ist eine Zeitzone nicht nur ein Versatz von GMT. Es ist ein Gebiet, in dem die Zeitregeln durch lokale Standards festgelegt werden. Einige Länder haben Sommerzeit und schalten die Sommerzeit zu unterschiedlichen Zeiten ein. Normalerweise ist es wichtig, die tatsächliche Zone zu ermitteln, nicht nur den aktuellen Versatz.

Wenn Sie diese Zeitzone speichern möchten, beispielsweise in den Benutzereinstellungen, möchten Sie die Zone und nicht nur den Versatz. Für Echtzeitkonvertierungen spielt es keine Rolle.

Um die Zeitzone mit Javascript zu erhalten, können Sie Folgendes verwenden:

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

Ich fand es jedoch einfacher, einfach dieses robuste Plugin zu verwenden, das die Olsen-formatierte Zeitzone zurückgibt:

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

Keyo
quelle
22

Mit der PHP- dateFunktion erhalten Sie das Datum und die Uhrzeit des Servers, auf dem sich die Site befindet. Die einzige Möglichkeit, die Benutzerzeit zu ermitteln, ist die Verwendung von JavaScript.

Ich empfehle Ihnen jedoch, wenn für Ihre Website eine Registrierung erforderlich ist, der Benutzer am besten zu fragen, ob eine Registrierung als Pflichtfeld erforderlich ist. Sie können verschiedene Zeitzonen auf der Registerseite auflisten und in der Datenbank speichern. Wenn sich der Benutzer danach bei der Site anmeldet, können Sie die Standardzeitzone für diese Sitzung gemäß der vom Benutzer ausgewählten Zeitzone festlegen.

Mit der PHP-Funktion können Sie eine bestimmte Zeitzone einstellen date_default_timezone_set. Dadurch wird die angegebene Zeitzone für Benutzer festgelegt.

Grundsätzlich geht die Zeitzone der Benutzer auf die Clientseite, daher müssen wir dafür JavaScript verwenden.

Unten finden Sie das Skript zum Abrufen der Zeitzone von Benutzern mithilfe von PHP und 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();
?>

Aus meiner Sicht ist es jedoch besser, die Benutzer zu fragen, ob eine Registrierung in Ihrem Projekt obligatorisch ist.

Sanjay Khatri
quelle
22

Verwenden Sie die IP-Adresse nicht, um den Standort (und damit die Zeitzone) endgültig zu bestimmen. Dies liegt daran, dass IP-Adressen bei NAT, Proxys (die immer beliebter werden) und VPNs nicht unbedingt den tatsächlichen Standort des Benutzers realistisch widerspiegeln, sondern den Standort, an dem sich die IP-Adresse befindet Server, die diese Protokolle implementieren, befinden sich.

Ähnlich wie US-Vorwahlen angesichts der Beliebtheit der Nummernübertragbarkeit für die Lokalisierung eines Telefonbenutzers nicht mehr nützlich sind.

Die IP-Adresse und andere oben gezeigte Techniken sind nützlich, um einen Standard vorzuschlagen , den der Benutzer anpassen / korrigieren kann.

Jaime G.
quelle
21

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

Geben Sie für diese Funktion einfach Ihre Zeiten im Unix-Zeitstempelformat an. JavaScript kennt bereits die Zeitzone des Benutzers.

So was:

PHP:

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

Dadurch werden die Zeiten immer korrekt angezeigt, basierend auf der Zeitzone, die die Person auf ihrer Computeruhr eingestellt hat. Es ist nicht nötig, irgendjemanden etwas zu fragen und es an Orten aufzubewahren, Gott sei Dank!

Envis
quelle
$ unix_timestamp_ofshiz? Hier fehlt etwas und funktioniert nicht ganz, obwohl dies eine gute Antwort sein könnte.
20

Einfach, verwenden Sie einfach die JavaScript- getTimezoneOffsetFunktion wie folgt:

-new Date().getTimezoneOffset()/60;
JoeyFur62
quelle
1
Dies ist eine Javascript-Funktion, keine PHP-Funktion.
Cincodenada
Außerdem wird nur der aktuelle Zeitzonenversatz zurückgegeben - nicht die Zeitzone . Siehe das Zeitzonen-Tag-Wiki .
Matt Johnson-Pint
3
Dies ist nur eine Kopie der akzeptierten Antwort, warum Sie überhaupt darüber abstimmen.
Rambatino
19

Die Magie scheint alles zu sein

visitortime.getTimezoneOffset()

Das ist cool, das wusste ich nicht. Funktioniert es in Internet Explorer usw.? Von dort aus sollten Sie in der Lage sein, JavaScript für Ajax zu verwenden, Cookies zu setzen, was auch immer. Ich würde wahrscheinlich selbst die Cookie-Route gehen.

Sie müssen dem Benutzer jedoch erlauben, es zu ändern. Wir haben vor einiger Zeit versucht, Geolocation (über maxmind) zu verwenden, um dies zu tun, und es war ziemlich oft falsch - genug, um es nicht wert zu machen, also ließen wir den Benutzer es einfach in seinem Profil festlegen und zeigten Benutzern, die dies tun habe ihre noch nicht eingestellt.

Orion Edwards
quelle
15

In diesem Artikel (mit Quellcode) wird erläutert, wie die lokalisierte Zeit in einer ASP.NET-Anwendung (VB.NET, C #) ermittelt und verwendet wird:

Es ist Zeit

Kurz gesagt, der beschriebene Ansatz basiert auf der JavaScript- getTimezoneOffsetFunktion, die den Wert zurückgibt, der im Sitzungscookie gespeichert und von CodeBehind zum Anpassen der Zeitwerte zwischen GMT und Ortszeit verwendet wird. Das Schöne ist, dass der Benutzer die Zeitzone nicht angeben muss (der Code erledigt dies automatisch). Es ist mehr involviert (aus diesem Grund verlinke ich auf den Artikel), aber der bereitgestellte Code macht die Verwendung wirklich einfach. Ich vermute, dass Sie die Logik in PHP und andere Sprachen konvertieren können (solange Sie ASP.NET verstehen).

Alek Davis
quelle
1
Der Link ist tot. Ich denke, dies ist der alternative Link: devproconnections.com/article/aspnet2/it-s-about-time-122778
Gan
1
Der Artikel ist auch hier als PDF-Formular verfügbar: app.box.com/shared/bfvvmidtyg
Ivaylo Slavov
Die in diesem Artikel beschriebene Methode zum Konvertieren der UTC-Serverzeit in die lokale Clientzeit ist falsch. Die Verwendung des aktuellen Client-Offsets zum Anpassen der UTC-Zeiten auf dem Server führt zu falschen "lokalen" Zeiten für ein halbes Jahr für Client-Gebietsschemas, in denen die Sommerzeit eingehalten wird. Stellen Sie sich dieses Szenario vor: Ein Kunde in Großbritannien legt am 14. Januar 2013 (GMT + 0000 Standardzeit) ein Datum und eine Uhrzeit für den 21. August 2015 um 14:00 Uhr (GMT + 0100 Sommerzeit) fest. Dies wird auf dem Server bis zum 21. August 2015 um 13:00 UTC normalisiert. An dem Tag, an dem dies auftritt, ist der Client-Offset 0, sodass die an den Client zurückgesendete Zeit der 21. August 2015 um 13:00 Uhr ist.
Stephen Blair
Gültiger Punkt, aber ich habe nicht behauptet, dass dies eine kugelsichere Lösung ist. Wenn Sie eine wirklich zeitkritische Lösung implementieren müssen, beispielsweise eine Anwendung zur Buchung von Bahntickets, müssen Sie eine umfassendere (und komplexere) Lösung finden. Für viele Apps wäre dies jedoch kein Problem. In vielen Fällen möchten wir GMT-Werte für die aktuelle Sitzung lokalisieren. Wenn Sie eine Anwendung haben, die auch in Zukunft einen Zeitstempel für einige speichern muss und DTS nicht tolerieren kann, besteht eine geeignete Möglichkeit darin, eine Option zum direkten Sparen von Zeit direkt in GMT anzubieten. Wenn Sie eine bessere Option kennen, teilen Sie diese bitte mit.
Alek Davis
14

Wenn Sie OpenID zur Authentifizierung verwenden, löst die Simple Registration Extension das Problem für authentifizierte Benutzer (Sie müssen von tz in numerisch konvertieren).

Eine andere Möglichkeit wäre, die Zeitzone aus den Länderpräferenzen des Benutzeragenten abzuleiten. Dies ist eine etwas grobe Methode (funktioniert nicht für en-US), macht aber eine gute Annäherung.

Dmitry Shechtman
quelle
13

Mit JavaScript und PHP ist das ganz einfach:

Obwohl der Benutzer mit seiner internen Uhr und / oder Zeitzone herumspielen kann, bleibt der beste Weg, den ich bisher gefunden habe, um den Offset zu erhalten new Date().getTimezoneOffset(); . Es ist nicht invasiv, verursacht keine Kopfschmerzen und macht es überflüssig, sich auf Dritte zu verlassen.

Angenommen, ich habe eine Tabelle, usersdie ein Feld date_created int(13)zum Speichern von Unix-Zeitstempeln enthält.

Unter der Annahme einen Client creates a new account, Daten empfingen durch post, und ich brauche , um insert/updatedie date_created columnmit dem Unix - Zeitstempel des Clients, nicht dem Server.

Da das timezoneOffset zum Zeitpunkt des Einfügens / Aktualisierens benötigt wird, wird es beim Senden des Formulars als zusätzliches $ _POST-Element übergeben, sodass es nicht mehr in Sitzungen und / oder Cookies gespeichert werden muss und auch keine zusätzlichen Servertreffer erforderlich sind.

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;

Angenommen, der Server empfängt tzoals $_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);

Einfügen / aktualisieren date_created=$user_timestamp .

Beim Abrufen von date_created können Sie den Zeitstempel folgendermaßen konvertieren:

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

Dieses Beispiel entspricht möglicherweise den Anforderungen beim Einfügen eines firstZeitstempels. Wenn es sich um einen zusätzlichen Zeitstempel oder eine zusätzliche Tabelle handelt, sollten Sie den tzo-Wert zur späteren Bezugnahme in die Benutzertabelle einfügen oder festlegen als Sitzung oder als Cookie.

PS ABER was ist, wenn der Benutzer reist und die Zeitzonen wechselt? Loggt sich bei GMT + 4 ein, fährt schnell zu GMT-1 und meldet sich erneut an. Der letzte Login würde in der Zukunft sein.

Ich denke ... wir denken zu viel.

Mann
quelle
13

Sie können dies auf dem Client mit der Zeitzone tun und den Wert an den Server senden. Beispielnutzung:

> moment.tz.guess()
"America/Asuncion"
Tomas Tomecek
quelle
5
Der Funktionsname sagt alles über seine Genauigkeit aus ;-)
Legends
Heutzutage empfehle ich moment.js nicht mehr. Derzeit gibt es weitaus kleinere Alternativen ( dayjs , date-fns ). Der Moment ist riesig .
Dan Dascalescu
11

Das Abrufen eines gültigen Zeitzonennamens für die TZ-Datenbank in PHP erfolgt in zwei Schritten:

  1. Mit JavaScript erhalten Sie einen Zeitzonenversatz in Minuten getTimezoneOffset. Dieser Offset ist positiv, wenn die lokale Zeitzone hinter UTC liegt, und negativ, wenn sie vor uns liegt. Sie müssen dem Offset also ein entgegengesetztes Vorzeichen hinzufügen.

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

    Übergeben Sie diesen Offset an PHP.

  2. In PHP konvertieren Sie diesen Offset in einen gültigen Zeitzonennamen mit der Funktion timezone_name_from_abbr .

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

Ich habe einen Blog-Beitrag darüber geschrieben: So erkennen Sie die Benutzerzeitzone in PHP . Es enthält auch eine Demo.

Nützlicher Winkel
quelle
1
Ich denke, ein einfacherer Prozess ist es, ihn anzurufen Intl.DateTimeFormat().resolvedOptions().timeZoneund an den Webserver zu senden. Ref: stackoverflow.com/questions/9772955/…
Michael Tsang
9

Ein einfacher Weg, dies zu tun, ist die Verwendung von:

new Date().getTimezoneOffset();
Naeem Ul Wahhab
quelle
8
Warum haben Sie eine identische Antwort (von John Isaacks) vor 2 Jahren erneut veröffentlicht: stackoverflow.com/a/1809974/836407 ?
chown
2
Außerdem wird nur der aktuelle Zeitzonenversatz zurückgegeben - nicht die Zeitzone . Siehe das Zeitzonen-Tag-Wiki .
Matt Johnson-Pint
8

Eine mögliche Option ist die Verwendung des DateHeader-Felds, das in RFC 7231 definiert ist und die Zeitzone enthalten soll. Natürlich kann nicht garantiert werden, dass der Wert wirklich die Zeitzone des Kunden ist, aber es kann ein bequemer Ausgangspunkt sein.

Berislav Lopac
quelle
1
Leider scheint dieser Header hauptsächlich für Antworten und nicht für Anfragen gedacht zu sein: "Ein Benutzeragent KANN in einer Anfrage ein Datum-Header-Feld senden, dies wird jedoch im Allgemeinen nicht der Fall sein, es sei denn, es wird angenommen, dass er nützliche Informationen an den Server übermittelt." Ich habe es gerade überprüft und Firefox sendet es nicht.
IMSoP
8

Hier ist, wie ich es mache. Dadurch wird die PHP-Standardzeitzone auf die lokale Zeitzone des Benutzers festgelegt. Fügen Sie einfach oben auf all Ihren Seiten Folgendes ein:

<?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
?>
Dane Iracleous
quelle
1
Dies berücksichtigt keine "Sommerzeit" -Anpassungen - ein Benutzer in Dublin würde im Winter mit "Europa / Dublin" übereinstimmen, im Sommer mit "Europa / Belgrad". Wenn Sie den aktuellen Versatz verwenden, können Sie vernünftigerweise nur diesen Versatz annehmen, keine geografische Kennung.
IMSoP
8

Versuchen Sie diesen PHP-Code:

<?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'];
?>
pckabeer
quelle