WebサーバーがWebページ内のユーザーのタイムゾーンを判別できる標準的な方法はありますか?
おそらくHTTPヘッダーまたはuser-agent
文字列の一部からですか?
WebサーバーがWebページ内のユーザーのタイムゾーンを判別できる標準的な方法はありますか?
おそらくHTTPヘッダーまたはuser-agent
文字列の一部からですか?
回答:
-new Date().getTimezoneOffset()/60;
このメソッドgetTimezoneOffset()
は、GMTから時間を差し引いて、分数を返します。したがって、GMT-8に住んでいる場合、480を返します。
これを時間で表すには、60で除算します。また、符号が必要なものと反対であることにも注意してください。これは、タイムゾーンのGMTからのオフセットではなく、タイムゾーンからのGMTのオフセットを計算しています。これを修正するには、単に-1を掛けます。
また、w3schoolによると、
夏時間を使用する習慣があるため、戻り値は定数ではありません。
>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
私が見てきたタイムゾーンを決定する最も一般的な(==標準?)方法は、単にユーザー自身に尋ねることです。Webサイトがサブスクリプションを必要とする場合、これはユーザーのプロファイルデータに保存できます。anonユーザーの場合、日付はUTCまたはGMTなどで表示できます。
私は賢い首謀者になるつもりはありません。場合によっては、プログラミングコンテキストの外では、問題によってはより細かい解決策がある場合もあります。
HTTP仕様に含めることを提案されていますが、これまでのところクライアントのタイムゾーンを報告するHTTPヘッダーはありません。
もし私だったら、おそらくクライアントサイドのJavaScriptを使ってタイムゾーンを取得してから、Ajaxなどを使ってサーバーに送信しようとするでしょう。
JavaScriptは、クライアントのローカル時間を取得する最も簡単な方法です。XMLHttpRequestを使用することをお勧めしますをて現地時間を送り返すます。これが失敗した場合は、IPアドレスに基づいて検出されたタイムゾーンにフォールバックします。
地理位置情報に関しては、いくつかのプロジェクトでMaxMind GeoIPを使用しましたが、うまく機能しますが、タイムゾーンデータを提供するかどうかはわかりません。それはあなたがお金を払うサービスであり、彼らはあなたのデータベースに毎月更新を提供します。いくつかのWeb言語でラッパーを提供します。
まず、JavaScriptでのタイムゾーン検出は不完全であることを理解してください。オブジェクトのインスタンスを使用して特定の日時のローカルタイムゾーンオフセットを取得できますが、これは次のような完全なIANAタイムゾーンとはまったく異なりますgetTimezoneOffset
Date
America/Los_Angeles
ます。
ただし、機能するオプションがいくつかあります。
const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tzid);
結果は、コードが実行されているコンピューターのIANAタイムゾーン設定を含む文字列です。
サポートされる環境は、Intl互換性表にリストされています。展開DateTimeFormat
のセクションを、そして名前が付けられた機能を見てresolvedOptions().timeZone defaults to the host environment
。
Luxonなどの一部のライブラリは、このAPIを使用して、などの関数を通じてタイムゾーンを決定しますluxon.Settings.defaultZoneName
。
Intl
APIが利用可能な場合はまずAPIを試し、利用できない場合は、結果を使用して内部データセットから適切なタイムゾーンを選択することにより、いくつかの異なる時点でオブジェクトのgetTimezoneOffset
機能に問い合わせDate
ます。jsTimezoneDetectとmoment-timezoneの両方にこの機能があります。
// using jsTimeZoneDetect
var tzid = jstz.determine().name();
// using moment-timezone
var tzid = moment.tz.guess();
どちらの場合も、結果は推測としてのみ考えることができます。多くの場合、推測は正しいかもしれませんが、すべてではありません。
さらに、これらのライブラリは定期的に更新して、多くの古いJavaScript実装がローカルタイムゾーンの現在の夏時間ルールのみを認識しているという事実に対抗する必要があります。 詳細はこちら。
最終的に、より良いアプローチは、実際にユーザーにタイムゾーンを尋ねることです。変更可能な設定を提供します。上記のオプションのいずれかを使用してデフォルト設定を選択できますが、アプリからそれを逸脱することを不可能にしないでください。
また、ユーザーのコンピューターのタイムゾーン設定にまったく依存しないというまったく異なるアプローチもあります。代わりに、緯度と経度の座標を収集できる場合は、これらの方法のいずれかを使用してそれらをタイムゾーンに解決できます。これはモバイルデバイスでうまく機能します。
これは、ブラウザーが使用されているタイムゾーンを判別するための堅牢なJavaScriptソリューションです。
>>> var timezone = jstz.determine();
>>> timezone.name();
"Europe/London"
https://bitbucket.org/pellepim/jstimezonedetect
付録1:このプロジェクトはGitHubにあります:https : //github.com/pellepim/jstimezonedetect
これはより完全な方法です。
以下はその抜粋です。
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を使用)
Africa/Johannesburg
Europe/Istanbul
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)または現在のタイムゾーンを返します。
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();
して、実際のタイムゾーン名を取得するのと同じようなこともできます
タイムゾーンを取得する詳細な回答はまだ見ていません。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形式のタイムゾーンを返すこの堅牢なプラグインを使用する方が簡単であることがわかりました。
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();
?>
しかし、私の見解によれば、プロジェクトで登録が必須かどうかをユーザーに尋ねた方がよいでしょう。
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>';
これにより、ユーザーが自分のコンピューターの時計に設定したタイムゾーンに基づいて、時刻が常に正しく表示されます。誰にも何も聞いて場所に保存する必要はありません、神に感謝します!
簡単です。次のようにJavaScript getTimezoneOffset
関数を使用するだけです。
-new Date().getTimezoneOffset()/60;
魔法はすべてにあるようです
visitortime.getTimezoneOffset()
それはクールです、私はそれについて知りませんでした。Internet Explorerなどで動作しますか?そこから、JavaScriptをAjaxに使用したり、Cookieを設定したりできます。たぶん私はクッキーのルートを自分で行くでしょう。
ただし、ユーザーが変更できるようにする必要があります。私たちは(maxmindを介して)地理位置情報を使用してこれを実行しようとしましたが、それはかなり頻繁に間違っていました。まだ設定していません。
ASP.NET(VB.NET、C#)アプリケーションでローカライズされた時間を特定して使用する方法を説明する記事(ソースコード付き)は次のとおりです。
つまり、説明されているアプローチはJavaScript getTimezoneOffset
関数に依存しています。JavaScript 関数は、セッションCookieに保存され、コードビハインドがGMTと現地時間の時間値を調整するために使用する値を返します。良い点は、ユーザーがタイムゾーンを指定する必要がないことです(コードが自動的に行います)。もっと複雑ですが(これが私が記事にリンクする理由です)、提供されたコードはそれを本当に使いやすくします。ロジックをPHPや他の言語に変換できると思います(ASP.NETを理解している限り)。
認証にOpenIDを使用している場合、Simple Registration Extensionは認証されたユーザーの問題を解決します(tzから数値に変換する必要があります)。
別のオプションは、ユーザーエージェントの国設定からタイムゾーンを推測することです。これはやや粗雑な方法ですが(en-USでは機能しません)、適切な概算になります。
JavaScriptとPHPを使用すると簡単です。
ユーザーが自分の内部時計やタイムゾーンを変更することはできますが、オフセットを取得するためにこれまでに見つけた最良の方法は残っていnew Date().getTimezoneOffset();
ます。それは非侵襲的で、頭痛を与えず、第三者に依存する必要性を排除します。
たとえば、Unixタイムスタンプを格納するためのusers
フィールドを含むテーブルがあるとしますdate_created int(13)
。
クライアントと仮定するとcreates a new account
、データがで受信されpost
、そして私が必要とするクライアントのUnixタイムスタンプではなく、サーバの持ちます。insert/update
date_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まで高速で移動し、再度ログインします。最後のログインは将来になるでしょう。
考えすぎます。
これをクライアントでmoment-timezoneを使用して実行し、値をサーバーに送信できます。使用例:
> moment.tz.guess()
"America/Asuncion"
PHPで有効なTZデータベースのタイムゾーン名を取得するには、2段階のプロセスを実行します。
JavaScriptを使用して、タイムゾーンオフセットを分単位で取得しgetTimezoneOffset
ます。このオフセットは、ローカルタイムゾーンがUTCより遅れている場合は正になり、遅れている場合は負になります。したがって、オフセットに反対の符号を追加する必要があります。
var timezone_offset_minutes = new Date().getTimezoneOffset();
timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
このオフセットをPHPに渡します。
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でユーザーのタイムゾーンを検出する方法。デモも含まれています。
Intl.DateTimeFormat().resolvedOptions().timeZone
それを呼び出してWebサーバーに送信することです。参考:stackoverflow.com/questions/9772955/...
これを行う簡単な方法は、以下を使用することです。
new Date().getTimezoneOffset();
1つの可能なオプションはDate
、RFC 7231で定義され、タイムゾーンを含めることになっているヘッダーフィールドを使用することです。もちろん、値が実際にクライアントのタイムゾーンであることは保証されていませんが、これは便利な出発点になる場合があります。
これが私のやり方です。これにより、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
?>