ユーザーのタイムゾーンを決定する


610

WebサーバーがWebページ内のユーザーのタイムゾーンを判別できる標準的な方法はありますか?

おそらくHTTPヘッダーまたはuser-agent文字列の一部からですか?


6
ユーザーに尋ねます。ユーザーのコンピューターからタイムゾーンを取得し、それが正しく設定されていない場合、どうしますか?
Rob Williams、

40
次に、ユーザーはおそらく気にしませんか?
10

2
あなたは意味ですかstackoverflow.com/q/1091372/218196
Felix Kling 2014年

2
残念ながら、この質問に対する回答では、ユーザープロファイリングとジオフェンシングも可能です。
William Entriken

1
なぜユーザーのタイムゾーンを知る必要があるのですか?
Braiam 2018年

回答:


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

このメソッドgetTimezoneOffset()は、GMTから時間を差し引いて、分数を返します。したがって、GMT-8に住んでいる場合、480を返します。

これを時間で表すには、60で除算します。また、符号が必要なものと反対であることにも注意してください。これは、タイムゾーンのGMTからのオフセットではなく、タイムゾーンからのGMTのオフセットを計算しています。これを修正するには、単に-1を掛けます。

また、w3schoolによると、

夏時間を使用する習慣があるため、戻り値は定数ではありません。


5
JavaScriptがサポートされていないブラウザを搭載した携帯電話を使用しているユーザーはどうですか?私は質問が好きです、ユーザーはHTTPヘッダー、ユーザーエージェントについて尋ねます...このワークサーバー側をできるだけ正確にする方法はありますか?
Nischal、2011

19
これは常にDSTで機能するとは限りません。Get timezone offsetは、まさにそれが言っていることを行います。オフセットを取得します。タイムゾーンは実際には地理的なエリアです。これは、ユーザーが住んでいる半球がわからないため、または国に夏時間があるかどうかがわからないため、夏時間には機能しません。なぜ、代わりにこれを使用しない:>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
Keyo

20
Keyoとは異なる点をお願いします。getTimezoneOffset()の定義(ECMA標準ecma-international.org/ecma-262/5.1/#sec-15.9.5.26に準拠)は、「ローカル時間とUTC時間の差を分単位で返します」です。-つまり、夏時間を考慮に入れる必要があります。Mozillaのドキュメントには、「夏時間のため、特定のロケールでもこの​​値が定数になるのを防ぐ」と書かれています。
xgretsch 2013

12
@xgretsch:GMTからのユーザーの現在のオフセットを取得します。同じ日に発生する別の時刻を提示している場合は問題ありません(現在の日付が切り替え日であり、間違っている可能性がある場合を除く)。ただし、GMTから同じオフセットを持つ多くのタイムゾーンがあり、それらは異なる切り替え日を持っているか、夏時間を使用しない場合があります。
マイクディミック2014

13
ここで注意すべきことが1つあります。一部の場所(カナダのニューファンドランドなど)のタイムゾーンは30分ずれているため、60で除算すると、回答が整数にならない場合があります。
Jason Walton

193

私が見てきたタイムゾーンを決定する最も一般的な(==標準?)方法は、単にユーザー自身に尋ねることです。Webサイトがサブスクリプションを必要とする場合、これはユーザーのプロファイルデータに保存できます。anonユーザーの場合、日付はUTCまたはGMTなどで表示できます。

私は賢い首謀者になるつもりはありません。場合によっては、プログラミングコンテキストの外では、問題によってはより細かい解決策がある場合もあります。


5
ユーザーが自分の場所に固有の開始時間(たとえば、全国の午前9時から11時)を持つ.icsファイルをダウンロードする場合はどうでしょうか?彼らは自分のタイムゾーンが何であるかを言うべきではありません。
Marcy Sutton

33
@Ishmaeel:しかし、ユーザーは海外旅行をするので、ネイティブではないタイムゾーンからログインするたびにタイムゾーンを知らせる必要はありません
Rajat Gupta

10
これは質問に答えるものではありません。それは明らかに彼が技術的な解決策を探していることを意味します。
G-Wiz

5
@gWiz OPは標準ソリューションを求めています。これはかなり標準的です。
Simon Bergot 2012

4
最善の解決策はおそらく、ユーザーに尋ねる(たとえば、レポートの上部にタイムゾーンのドロップダウンを提供する)一方で、ユーザーがモバイルにいるときにドロップダウンの選択をGPSが決定したタイムゾーンにデフォルト設定することです。ロケーション情報を提供するデバイス。それ以外の場合はデフォルトでUTCになります。
Triynko、2015

133

HTTP仕様に含めることを提案されていますが、これまでのところクライアントのタイムゾーンを報告するHTTPヘッダーはありません。

もし私だったら、おそらくクライアントサイドのJavaScriptを使ってタイムゾーンを取得してから、Ajaxなどを使ってサーバーに送信しようとするでしょう。


16
不思議なことに、これは質問に対する唯一の正しい答えです。サーバー側でそれを行う方法を尋ねます。投票数が多い他の回答がある理由は、クライアント側でそれを行う必要があるとわかったら、他の回答を使用することになるためだと思います。しかし、私見で別の答えを支持している人は、この回答も支持しているはずです。
TTT

最善の方法は、geo-ipロケーションを使用して可能なタイムゾーンをソートし、デフォルトでユーザーエージェントの時間オフセットに一致する(近い)最初の1つを選択することです(JavaScriptが必要です)。それでも、この方法で正しくないものを選択した後でタイムゾーンを修正する方法を提供する必要があります。
ミッコランタライネン2017

@MikkoRantalainenは、ヘッダーで自分自身を常にアドバタイズするとは限らないため、プロキシを使用する場合は注意してください。
Matthieu

@Matthieu今日より良い答えがあります:stackoverflow.com/a/11836123/334451
ミッコランタライネン2017年

2
これが文字通り、提起された質問に実際に対処した唯一の回答です。
lscoughlin

54

JavaScriptは、クライアントのローカル時間を取得する最も簡単な方法です。XMLHttpRequestを使用することをお勧めしますをて現地時間を送り返すます。これが失敗した場合は、IPアドレスに基づいて検出されたタイムゾーンにフォールバックします。

地理位置情報に関しては、いくつかのプロジェクトでMaxMind GeoIPを使用しましたが、うまく機能しますが、タイムゾーンデータを提供するかどうかはわかりません。それはあなたがお金を払うサービスであり、彼らはあなたのデータベースに毎月更新を提供します。いくつかのWeb言語でラッパーを提供します。


GeoIP(現時点では無料バージョンが利用可能です)などのデータベースから取得した緯度と経度を、そのような座標をタイムゾーンに変換するデータベースと組み合わせることができるため、私はこの回答に投票しました。GeoNamesには後者のデータベースがあります。
ピーターO.

MaxMind GeoIPデータベース/ APIの現在のバージョン(無料と有料の両方)は、確かにタイムゾーン情報を提供します(私のタイムゾーンに対して「ヨーロッパ/ロンドン」を返します)。GeoIPシステムの古いバージョンかどうか覚えていません。同じことをしましたが、今はとてもうまくいきます!MaxMindフィールドの名前は「time_zone」、「time_zone_name」です。
Matthew Slyman、2015

51

まず、JavaScriptでのタイムゾーン検出は不完全であることを理解してください。オブジェクトのインスタンスを使用して特定の日時のローカルタイムゾーンオフセットを取得できますが、これは次のような完全なIANAタイムゾーンとはまったく異なりますgetTimezoneOffsetDateAmerica/Los_Angelesます。

ただし、機能するオプションがいくつかあります。

  • 最新のブラウザのほとんどは、ECMAScript国際化APIの実装でIANAタイムゾーンをサポートしているため、次のようにできます。

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

結果は、コードが実行されているコンピューターのIANAタイムゾーン設定を含む文字列です。

サポートされる環境は、Intl互換性表にリストされています。展開DateTimeFormatのセクションを、そして名前が付けられた機能を見てresolvedOptions().timeZone defaults to the host environment

  • Luxonなどの一部のライブラリは、このAPIを使用して、などの関数を通じてタイムゾーンを決定しますluxon.Settings.defaultZoneName

    • 古いWebブラウザーなど、より幅広い環境のセットをサポートする必要がある場合は、ライブラリーを使用して、タイムゾーンで適切な推測を行うことができます。IntlAPIが利用可能な場合はまずAPIを試し、利用できない場合は、結果を使用して内部データセットから適切なタイムゾーンを選択することにより、いくつかの異なる時点でオブジェクトのgetTimezoneOffset機能に問い合わせDateます。

    jsTimezoneDetectmoment-timezoneの両方にこの機能があります。

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

    どちらの場合も、結果は推測としてのみ考えることができます。多くの場合、推測は正しいかもしれませんが、すべてではありません。

    さらに、これらのライブラリは定期的に更新して、多くの古いJavaScript実装がローカルタイムゾーンの現在の夏時間ルールのみを認識しているという事実に対抗する必要があります。 詳細はこちら。

最終的に、より良いアプローチは、実際にユーザーにタイムゾーンを尋ねることです。変更可能な設定を提供します。上記のオプションのいずれかを使用してデフォルト設定を選択できますが、アプリからそれを逸脱することを不可能にしないでください。

また、ユーザーのコンピューターのタイムゾーン設定にまったく依存しないというまったく異なるアプローチもあります。代わりに、緯度と経度の座標を収集できる場合は、これらの方法のいずれかを使用してそれらをタイムゾーンに解決できます。これはモバイルデバイスでうまく機能します。


ユーザーの地理的位置(つまり、ロケール)を使用してタイムゾーンを推定することにも欠陥があります。ユーザーは、同じ時刻を表示する(またはしない)場合でも、ローカルタイムゾーンではない特定のタイムゾーンをデバイスで使用したい場合があります。たとえば、旅行者は頻繁にタイムゾーンを通常の地域に設定したままデバイスを離れ、通知なしに日付と時刻が異なるオフセットを使用することを期待しません。私はここで個人的な経験から話しているかもしれません…;-)
RobG

ロブをトローリングしているかどうかわからない。;)しかし、これらのアプローチはいずれもロケールを使用しませんが、デバイスの設定を使用するため、ポイントに一致します。(前の段落で述べた代替アプローチのみが現在の場所を使用します。)
Matt Johnson-Pint

用語の注記を用いて説明します。「ロケール」は、ユーザーの地理的な場所ではありません。「ロケール」は、言語、数値形式、カレンダーなどの設定のグループです。たとえば、de_DEロケールは、デフォルト言語としてドイツ語、デフォルト通貨としてユーロ、小数点記号としてカンマ、桁区切り記号としてピリオド、およびグレゴリオ暦を指定します。カレンダーとして。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…を
azernik

49

これは、ブラウザーが使用されているタイムゾーンを判別するための堅牢なJavaScriptソリューションです。

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

https://bitbucket.org/pellepim/jstimezonedetect

付録1:このプロジェクトはGitHubにあります:https : //github.com/pellepim/jstimezonedetect


14
リンクのみの回答はお勧めしません。リンクが消えると、回答は役に立たなくなるためです。リンクをたどらないと、読者はそれが良い答えを与えるかどうかわかりません。この場合、これがデータベースベースのアプローチで識別を行うサードパーティのライブラリであることを明確にし、その操作の原理のいくつかを説明することができます。
IMSoP 2015

1
この!これが方法です。シンプルなライブラリ、DSTを適切に処理します。他の回答はWTFでいっぱいで、多くはDSTを行いません。
Dirbaio 2016年

1
このライブラリはとても賢いです。これは、UTCへの現在のオフセットを照会し、次にUTCへのオフセットが変更されるまで秒数を加算または減算することによってJavaScript Dateオブジェクト時間を調整することによって機能します。このライブラリーは、この方法を使用して、タイムゾーンを一意に識別するのに十分な多くのDST変更を計算します。線形検索の代わりにバイナリ検索を行った場合、ライブラリのパフォーマンスはさらに向上すると思います。戻り値は、IANAゾーン情報キー(別名Olsonタイムゾーンデータベース)です。
ミッコランタライネン

3
このライブラリは不要になりました。最新のブラウザは、IANAタイムゾーン文字列を返すIntl APIをサポートしています。この回答を参照してください。
Dan Dascalescu

42

これはより完全な方法です。

  1. ユーザーのタイムゾーンオフセットを取得する
  2. 夏時間の境界で数日間テストして、夏時間を使用するゾーンにあるかどうかを確認します。

以下はその抜粋です。

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

JSからTZおよびDSTを取得する(Way Back Machineを使用)


これは私のために働いた!コードのいくつかの更新については、ブログ投稿の下のコメントを読んでください。
arlomedia

これでも、+ 02:00などのタイムゾーンの標準オフセットのみが返されます。またはなど、ユーザーのタイムゾーンを特定するのに十分な情報は提供されません。タイムゾーンタグwikiをご覧ください。Africa/JohannesburgEurope/Istanbul
Matt Johnson-Pint 14

32

Unkwntechのアプローチを使用して、jQueryとPHPを使用する関数を作成しました。これはテストされ、機能します!

タイムゾーンを変数として使用するPHPページで、ページの上部近くに次のコードスニペットを配置します。

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

これにより、これから作成するセッション変数「time」が読み取られます。

同じページの<head>で、まずjQueryを含める必要があります。

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

また、<head>の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>

お気づきかもしれませんが、URLを実際のドメインに変更する必要があります。

最後に一つだけ。おそらくtimezone.phpが一体何なのか疑問に思っているでしょう。まあ、それはこれだけです:(timezone.phpという新しいファイルを作成し、上記のURLでそれをポイントします)

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

これが正しく機能する場合、最初にページをロードし、JavaScriptを実行して、ページを再ロードします。その後、$ timezone変数を読み取り、それを自由に使用できるようになります。現在のUTC / GMTタイムゾーンオフセット(GMT -7)または現在のタイムゾーンを返します。


私はこれが好きですが、現在の$ _SESSION ['time']をチェックし、JavaScriptが異なる場合にのみJavaScriptをリロードさせるかもしれません
Christopher Chase

1
これを転送するには、セッションよりもCookieを使用する方が簡単です。これは、PHPセッションをロックして非シリアル化すると、アプリの速度が低下する可能性があるためです。効率を最大にするために、値をセッションにコピーしてCookieを削除し、後続のリクエストで送信されないようにすることができます。
IMSoP 2015

25

jQueryを使用したAJAXリクエストでタイムゾーンオフセットをHTTPヘッダーとして送信するには

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

http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/を使用moment.tz.guess();して、実際のタイムゾーン名を取得するのと同じようなこともできます


1
これは、タイムゾーンではなく、現在のタイムゾーンオフセットのみを返します。タイムゾーンタグwikiをご覧ください。
Matt Johnson-Pint 14

タイムゾーン名について同じことを行うための情報を含むように編集されました。
philfreo 2017年

24

タイムゾーンを取得する詳細な回答はまだ見ていません。IPアドレスでジオコーディングしたり、PHP(lol)を使用したり、オフセットから誤って推測したりする必要はありません。

まず、タイムゾーンはGMTからの単なるオフセットではありません。これは、時間の規則が地域の基準によって設定されている土地の領域です。一部の国では夏時間が設定されており、DSTをオンにするタイミングが異なります。通常、現在のオフセットだけでなく、実際のゾーンを取得することが重要です。

このタイムゾーンを保存する場合、たとえばユーザー設定で、オフセットだけでなくゾーンが必要です。リアルタイムの変換の場合はそれほど問題になりません。

これで、JavaScriptでタイムゾーンを取得するには、これを使用できます。

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

ただし、Olsen形式のタイムゾーンを返すこの堅牢なプラグインを使用する方が簡単であることがわかりました。

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


22

PHP date関数を使用すると、サイトが配置されているサーバーの日時を取得できます。ユーザー時間を取得する唯一の方法は、JavaScriptを使用することです。

ただし、サイトに登録が必要な場合は、ユーザーに必須フィールドとして登録するよう依頼するのが最善の方法です。登録ページにさまざまなタイムゾーンをリストして、データベースに保存できます。この後、ユーザーがサイトにログインすると、ユーザーが選択したタイムゾーンに従って、そのセッションのデフォルトのタイムゾーンを設定できます。

PHP関数を使用して、特定のタイムゾーンを設定できますdate_default_timezone_set。これにより、ユーザーに指定されたタイムゾーンが設定されます。

基本的に、ユーザーのタイムゾーンはクライアント側になるため、JavaScriptを使用する必要があります。

以下は、PHPと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();
?>

しかし、私の見解によれば、プロジェクトで登録が必須かどうかをユーザーに尋ねた方がよいでしょう。


22

場所(およびタイムゾーン)を明確に決定するためにIPアドレスを使用しないでください。これは、NAT、プロキシ(人気が高まっている)、およびVPNの場合、IPアドレスは必ずしもユーザーの実際の場所ではなく、実際の場所を反映しているためです。これらのプロトコルを実装するサーバーが常駐します。

米国の市外局番は、番号の移植性の人気を考えると、電話ユーザーを見つけるのにもはや役に立たなくなっているのと同様です。

上記のIPアドレスとその他の手法は、ユーザーが調整/修正できるデフォルト提案するのに役立ちます。


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

この関数にUnixタイムスタンプ形式で時間を提供するだけです。JavaScriptはすでにユーザーのタイムゾーンを認識しています。

このような:

PHP:

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

これにより、ユーザーが自分のコンピューターの時計に設定したタイムゾーンに基づいて、時刻が常に正しく表示されます。誰にも何も聞いて場所に保存する必要はありません、神に感謝します!


$ unix_timestamp_ofshiz?これは良い答えであるように思われるかもしれませんが、ここで何かが欠けていて、うまく機能しません。

20

簡単です。次のようにJavaScript getTimezoneOffset関数を使用するだけです。

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

1
これはJavaScript関数であり、PHP関数ではありません。
cincodenada 2013

また、それだけを返し、現在のではない-タイムゾーンオフセットのタイムゾーンをタイムゾーンタグwikiをご覧ください。
Matt Johnson-Pint 14

3
これは承認された回答の単なるコピーであり、投票する理由さえあります。
Rambatino、2018年

19

魔法はすべてにあるようです

visitortime.getTimezoneOffset()

それはクールです、私はそれについて知りませんでした。Internet Explorerなどで動作しますか?そこから、JavaScriptをAjaxに使用したり、Cookieを設定したりできます。たぶん私はクッキーのルートを自分で行くでしょう。

ただし、ユーザーが変更できるようにする必要があります。私たちは(maxmindを介して)地理位置情報を使用してこれを実行しようとしましたが、それはかなり頻繁に間違っていました。まだ設定していません。


15

ASP.NET(VB.NET、C#)アプリケーションでローカライズされた時間を特定して使用する方法を説明する記事(ソースコード付き)は次のとおりです。

そろそろ時間だ

つまり、説明されているアプローチはJavaScript getTimezoneOffset関数に依存しています。JavaScript 関数は、セッションCookieに保存され、コードビハインドがGMTと現地時間の時間値を調整するために使用する値を返します。良い点は、ユーザーがタイムゾーンを指定する必要がないことです(コードが自動的に行います)。もっと複雑ですが(これが私が記事にリンクする理由です)、提供されたコードはそれを本当に使いやすくします。ロジックをPHPや他の言語に変換できると思います(ASP.NETを理解している限り)。


1
リンクが切れています。私はこれが代替リンクだと思います:devproconnections.com/article/aspnet2/it-s-about-time-122778
Gan

1
記事はPDFフォームでもこちらから入手できます:app.box.com/shared/bfvvmidtyg
Ivaylo Slavov

この記事で説明されているUTCサーバー時間をローカルクライアント時間に変換する方法は間違っています。サーバーのUTC時間を調整するために現在のクライアントオフセットを使用すると、夏時間を遵守するクライアントロケールの半年の「ローカル」時間が正しくなくなります。このシナリオを考えてみましょう:2013年1月14日(GMT + 0000標準時間)に英国のクライアントが2015年8月21日14:00(GMT + 0100夏時間)の日付と時刻を設定します。これは、サーバー上で2015年8月21日13:00 UTCに正規化されます。これが発生する日のクライアントオフセットは0なので、クライアントに送り返される時間は2015年8月21日13:00になります。
スティーブンブレア

妥当な点ですが、これが防弾ソリューションであるとは主張していません。本当に時間に敏感なソリューション、たとえば列車のチケット予約アプリケーションを実装する必要がある場合は、より包括的な(そして複雑なソリューション)を見つける必要があります。ただし、多くのアプリではこれは問題になりません。多くの場合、現在のセッションのGMT値をローカライズしたいからです。今後、タイムスタンプを保存する必要があるアプリケーションがあり、DTSを許容できない場合、適切な方法は、GMTで直接時間を節約するオプションを提示することです。より良いオプションを知っている場合は、共有してください。
Alek Davis、

14

認証にOpenIDを使用している場合、Simple Registration Extensionは認証されたユーザーの問題を解決します(tzから数値に変換する必要があります)。

別のオプションは、ユーザーエージェントの国設定からタイムゾーンを推測することです。これはやや粗雑な方法ですが(en-USでは機能しません)、適切な概算になります。


13

JavaScriptとPHPを使用すると簡単です。

ユーザーが自分の内部時計やタイムゾーンを変更することはできますが、オフセットを取得するためにこれまでに見つけた最良の方法は残っていnew Date().getTimezoneOffset();ます。それは非侵襲的で、頭痛を与えず、第三者に依存する必要性を排除します。

たとえば、Unixタイムスタンプを格納するためのusersフィールドを含むテーブルがあるとしますdate_created int(13)

クライアントと仮定するとcreates a new account、データがで受信されpost、そして私が必要とするクライアントのUnixタイムスタンプではなく、サーバの持ちます。insert/updatedate_created column

挿入/更新時にtimezoneOffsetが必要になるため、クライアントがフォームを送信するときに追加の$ _POST要素として渡されるため、セッションやCookieに保存する必要がなくなり、追加のサーバーヒットも発生しません。

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;

サーバーが次のように受信したtzoとし$_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);

挿入/更新date_created=$user_timestamp

date_createdを取得するときに、タイムスタンプを次のように変換できます。

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

さて、firstタイムスタンプを挿入することになると、この例は自分のニーズに合うかもしれません...追加のタイムスタンプまたはテーブルになると、将来の参照のためにユーザーテーブルにtzo値を挿入するか、それを設定することを検討できますセッションまたはCookieとして。

PSしかし、ユーザーが移動してタイムゾーンを切り替えるとどうなるでしょうか。GMT + 4にログインし、GMT-1まで高速で移動し、再度ログインします。最後のログインは将来になるでしょう。

考えすぎます。



11

PHPで有効なTZデータベースのタイムゾーン名を取得するには、2段階のプロセスを実行します。

  1. JavaScriptを使用して、タイムゾーンオフセットを分単位で取得しgetTimezoneOffsetます。このオフセットは、ローカルタイムゾーンがUTCより遅れている場合は正になり、遅れている場合は負になります。したがって、オフセットに反対の符号を追加する必要があります。

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

    このオフセットをPHPに渡します。

  2. PHPでは、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>

私はそれにブログ投稿を書きました:PHPでユーザーのタイムゾーンを検出する方法。デモも含まれています。


1
より簡単なプロセスは、Intl.DateTimeFormat().resolvedOptions().timeZoneそれを呼び出してWebサーバーに送信することです。参考:stackoverflow.com/questions/9772955/...
マイケル・ツァン


8

1つの可能なオプションはDateRFC 7231で定義され、タイムゾーンを含めることになっているヘッダーフィールドを使用することです。もちろん、値が実際にクライアントのタイムゾーンであることは保証されていませんが、これは便利な出発点になる場合があります。


1
残念ながら、そのヘッダーはリクエストではなく主に応答用に設計されているようです。「ユーザーエージェントはリクエストで日付ヘッダーフィールドを送信できますが、サーバーに有用な情報を伝えると信じられていない限り、通常は送信しません。」確認したところ、Firefoxから送信されませんでした。
IMSoP 2015

8

これが私のやり方です。これにより、PHPのデフォルトのタイムゾーンがユーザーのローカルタイムゾーンに設定されます。次のコードをすべてのページの上部に貼り付けてください。

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

1
これは「夏時間」の調整を考慮していません。ダブリンのユーザーは、冬は「ヨーロッパ/ダブリン」に一致しますが、夏は「ヨーロッパ/ベオグラード」に一致します。現在のオフセットを使用する場合、地理的な識別子ではなく、そのオフセットのみを合理的に想定できます。
IMSoP 2015

8

このPHPコードを試してください:

<?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'];
?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.