クライアント システムのタイム ゾーンに関係なく、クライアントの現地時間を取得する最良の方法は何ですか? アプリケーションを作成していますが、まずクライアントがアクセスしている場所の正確な日時を取得する必要があります。クライアント システムの IP アドレスを検出することにも欠点があり、クライアント システムのタイム ゾーンを検出することにはリスクが伴う場合があります。それで、間違った時刻と日付をクライアントに表示することは非常に恥ずかしいことなので、本当に信頼でき、エラーに対して脆弱ではない方法はありますか.
15 に答える
JavaScriptで?新しいDate オブジェクトをインスタンス化するだけです
var now = new Date();
これにより、クライアントの現地時間で新しい Date オブジェクトが作成されます。
試す
let s= new Date().toLocaleString();
console.log(s);
GMT/UTC に対するクライアントのタイムゾーンを知りたい場合は、次のようにします。
var d = new Date();
var tz = d.toString().split("GMT")[1].split(" (")[0]; // timezone, i.e. -0700
タイムゾーンの実際の名前が必要な場合は、これを試すことができます:
var d = new Date();
var tz = d.toString().split("GMT")[1]; // timezone, i.e. -0700 (Pacific Daylight Time)
更新 1
最初のコメントごとに、d.getTimezoneOffset()
UTC からの分単位のオフセットを取得するために使用することもできます。ただし、いくつかの落とし穴があります。
- 返される分数の符号 (+/-) は、おそらく予想とは逆です。UTC から8 時間遅れ
480
ている場合、 notが返され-480
ます。詳細なドキュメントについては、 MDNまたはMSDNを参照してください。 - 私が与えた2番目の例のように、クライアントが報告しているタイムゾーンを実際には返しません。現在、UTC からの分オフセットのみです。そのため、サマータイムに基づいて変更されます。
更新 2
文字列分割の例は機能しますが、読みにくい場合があります。これは、理解しやすく、おそらくより高速な正規表現バージョンです (ただし、どちらの方法も非常に高速です)。
GMT/UTC に対するクライアントのタイムゾーンを知りたい場合は、次のようにします。
var gmtRe = /GMT([\-\+]?\d{4})/; // Look for GMT, + or - (optionally), and 4 characters of digits (\d)
var d = new Date().toString();
var tz = gmtRe.exec(d)[1]; // timezone, i.e. -0700
タイムゾーンの実際の名前が必要な場合は、これを試してください:
var tzRe = /\(([\w\s]+)\)/; // Look for "(", any words (\w) or spaces (\s), and ")"
var d = new Date().toString();
var tz = tzRe.exec(d)[1]; // timezone, i.e. "Pacific Daylight Time"
これに取り組まなければならなかったので、答えを残すと思いました。jQuery は必要ありません オブジェクトが既にキャッシュされているため、以前は要素を更新していました。
最初に、必要な日付/時刻を HTML テンプレートに返す php 関数を作成しました。
/**
* Gets the current location time based on timezone
* @return string
*/
function get_the_local_time($timezone) {
//$timezone ='Europe/London';
$date = new DateTime('now', new DateTimeZone($timezone));
return array(
'local-machine-time' => $date->format('Y-m-d\TH:i:s+0000'),
'local-time' => $date->format('h:i a')
);
}
次に、これを HTML テンプレートで使用して初期時間を表示し、javascript で必要な日付形式を data 属性でレンダリングします。
<span class="box--location__time" data-time="<?php echo $time['local-machine-time']; ?>">
<?php echo $time['local-time']; ?>
</span>
次に、日付オブジェクトで getUTCHours を使用して、ユーザーのタイムゾーンに関係なく時間を返しました
getUTCHours() メソッドは、世界時に従って、指定された日時の時 (0 から 23 まで) を返します。
var initClocks = function() {
var $clocks = $('.box--location__time');
function formatTime(hours, minutes) {
if (hours === 0) {
hours = 12;
}
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
return {
hours: hours,
minutes: minutes
}
}
function displayTime(time, $clockDiv) {
var currentTime = new Date(time);
var hours = currentTime.getUTCHours();
var minutes = currentTime.getUTCMinutes();
var seconds = currentTime.getUTCSeconds();
var initSeconds = seconds;
var displayTime = formatTime(hours, minutes);
$clockDiv.html(displayTime.hours + ":" + displayTime.minutes + ":" + seconds);
setInterval(function() {
if (initSeconds > 60) {
initSeconds = 1;
} else {
initSeconds++;
}
currentTime.setSeconds(initSeconds);
hours = currentTime.getUTCHours();
minutes = currentTime.getUTCMinutes();
seconds = currentTime.getUTCSeconds();
displayTime = formatTime(hours, minutes);
$clockDiv.html(displayTime.hours + ":" + displayTime.minutes + ":" + seconds);
}, 1000);
}
$clocks.each(function() {
displayTime($(this).data('time'), $(this));
});
};
次に、setSeconds メソッドを使用して、ページが読み込まれてから経過した秒数に基づいて日付オブジェクトを更新し (単純な間隔関数)、HTML を更新します。
都市または場所の現地時間を表示する最も信頼できる方法は、Google Time Zone API などの Time Zone API を利用することです。それは正しいタイムゾーンを返し、さらに重要なことに、JavaScript の Date() オブジェクトを使用するだけでは、私が知る限り、任意の場所の夏時間のオフセットを返すことができません。API を使用して現地時間を取得および表示するための優れたチュートリアルがここにあります。
var loc = '35.731252, 139.730291' // Tokyo expressed as lat,lng tuple
var targetDate = new Date() // Current date/time of user computer
var timestamp = targetDate.getTime() / 1000 + targetDate.getTimezoneOffset() * 60 // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC
var apikey = 'YOUR_TIMEZONE_API_KEY_HERE'
var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + loc + '×tamp=' + timestamp + '&key=' + apikey
var xhr = new XMLHttpRequest() // create new XMLHttpRequest2 object
xhr.open('GET', apicall) // open GET request
xhr.onload = function() {
if (xhr.status === 200) { // if Ajax request successful
var output = JSON.parse(xhr.responseText) // convert returned JSON string to JSON object
console.log(output.status) // log API return status for debugging purposes
if (output.status == 'OK') { // if API reports everything was returned successfully
var offsets = output.dstOffset * 1000 + output.rawOffset * 1000 // get DST and time zone offsets in milliseconds
var localdate = new Date(timestamp * 1000 + offsets) // Date object containing current time of Tokyo (timestamp + dstOffset + rawOffset)
console.log(localdate.toLocaleString()) // Display current Tokyo date and time
}
} else {
alert('Request failed. Returned status of ' + xhr.status)
}
}
xhr.send() // send request
From: JavaScript と Google Time Zone API を使用して任意の都市の現地時間を表示する
これは、フェッチとhttps://worldtimeapi.org/apiを使用して 2020 年 9 月にうまく機能するバージョンです。
fetch("https://worldtimeapi.org/api/ip")
.then(response => response.json())
.then(data => console.log(data.dst,data.datetime));
独自の nodeJS エンドポイントを作成し、heroku などで公開してアクセスすることもできます。
require("http").createServer(function (q,r) {
r.setHeader("accees-control-allow-origin","*")
r.end(Date.now())
}).listen(process.env.PORT || 80)
次に、JSでアクセスします
fetch ("http://someGerokuApp")
.then(r=>r.text)
. then (r=>console.log(r))
これは、ノードアプリがホストされているコンピューターに相対的ですが、おそらく、何らかの方法で場所を取得し、現在のタイムゾーンに基づいて他のタイムゾーンに適合するさまざまなエンドポイントを提供できます (たとえば、サーバーがたまたまカリフォルニアにある場合、ニューヨークのタイムゾーンは1000*60*60*3
、Date.now() にミリ秒を追加して 3 時間を追加するだけです)
簡単にするために、サーバーから場所を取得して応答ヘッダーとして送信できる場合は、クライアント側でさまざまなタイムゾーンの計算を行うだけで済みます
実際、heroku を使用すると、https: //devcenter.heroku.com/articles/regions#specifying-a-region でデプロイするリージョンを指定できます。これを参照として使用できます。
編集は、タイムゾーンが日付文字列自体にあることに気づきました。クライアントが読み取るヘッダーとしてすべてを支払うことができます
require("http").createServer(function (q,r) {
var d= new Date()
r.setHeader("accees-control-allow-origin","*")
r.setHeader("zman", d.toString())
r.end(d.getTime())
}).listen(process.env.PORT || 80)