Apakah ada cara standar untuk server web untuk dapat menentukan zona waktu pengguna dalam halaman web?
Mungkin dari header HTTP atau bagian dari user-agent
string?
Apakah ada cara standar untuk server web untuk dapat menentukan zona waktu pengguna dalam halaman web?
Mungkin dari header HTTP atau bagian dari user-agent
string?
Jawaban:
-new Date().getTimezoneOffset()/60;
Metode ini getTimezoneOffset()
akan mengurangi waktu Anda dari GMT dan mengembalikan jumlah menit. Jadi jika Anda tinggal di GMT-8, itu akan mengembalikan 480.
Untuk menghitungnya menjadi berjam-jam, bagi dengan 60. Selain itu, perhatikan bahwa tandanya adalah kebalikan dari yang Anda butuhkan - itu menghitung offset GMT dari zona waktu Anda, bukan offset zona waktu Anda dari GMT. Untuk memperbaikinya, cukup kalikan dengan -1.
Perhatikan juga bahwa w3school mengatakan:
Nilai yang dikembalikan tidak konstan, karena praktik menggunakan Daylight Saving Time.
>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
Cara paling populer (== standar?) Untuk menentukan zona waktu yang pernah saya lihat adalah bertanya pada pengguna sendiri. Jika situs web Anda memerlukan berlangganan, ini dapat disimpan dalam data profil pengguna. Untuk pengguna lain, tanggal dapat ditampilkan sebagai UTC atau GMT atau semacamnya.
Saya tidak berusaha menjadi orang yang cerdas. Hanya saja kadang-kadang beberapa masalah memiliki solusi yang lebih baik di luar konteks pemrograman apa pun.
Tidak ada header HTTP yang akan melaporkan zona waktu klien sejauh ini meskipun telah disarankan untuk memasukkannya dalam spesifikasi HTTP.
Jika itu saya, saya mungkin akan mencoba mengambil zona waktu menggunakan JavaScript di sebelah klien dan kemudian mengirimkannya ke server menggunakan Ajax atau sesuatu.
JavaScript adalah cara termudah untuk mendapatkan waktu lokal klien. Saya akan menyarankan menggunakan XMLHttpRequest untuk mengirim kembali waktu setempat, dan jika itu gagal, kembali ke zona waktu yang terdeteksi berdasarkan alamat IP mereka.
Sejauh geolokasi, saya telah menggunakan MaxMind GeoIP pada beberapa proyek dan berfungsi dengan baik, meskipun saya tidak yakin apakah mereka menyediakan data zona waktu. Ini adalah layanan yang Anda bayar dan mereka memberikan pembaruan bulanan ke database Anda. Mereka menyediakan pembungkus dalam beberapa bahasa web.
Pertama, pahami bahwa deteksi zona waktu dalam JavaScript tidak sempurna. Anda bisa mendapatkan offset zona waktu lokal untuk tanggal dan waktu tertentu menggunakan getTimezoneOffset
instance Date
objek, tapi itu tidak sama dengan zona waktu IANA penuh seperti America/Los_Angeles
.
Ada beberapa opsi yang dapat bekerja:
const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tzid);
Hasilnya adalah string yang berisi pengaturan zona waktu IANA dari komputer tempat kode berjalan.
Lingkungan yang didukung tercantum dalam tabel kompatibilitas Intl . Buka DateTimeFormat
bagian itu, dan lihat fitur yang dinamai resolvedOptions().timeZone defaults to the host environment
.
Beberapa perpustakaan, seperti Luxon menggunakan API ini untuk menentukan zona waktu melalui fungsi-fungsi seperti luxon.Settings.defaultZoneName
.
Intl
API jika tersedia, dan ketika itu tidak tersedia, mereka menginterogasi getTimezoneOffset
fungsi Date
objek, untuk beberapa titik waktu yang berbeda, menggunakan hasil untuk memilih zona waktu yang sesuai dari set data internal.Baik jsTimezoneDetect dan moment-timezone memiliki fungsi ini.
// using jsTimeZoneDetect
var tzid = jstz.determine().name();
// using moment-timezone
var tzid = moment.tz.guess();
Dalam kedua kasus, hasilnya hanya dapat dianggap sebagai tebakan. Dugaan itu mungkin benar dalam banyak kasus, tetapi tidak semuanya.
Selain itu, perpustakaan ini harus diperbarui secara berkala untuk melawan fakta bahwa banyak implementasi JavaScript yang lebih tua hanya menyadari saat daylight saving waktu aturan untuk zona waktu lokal mereka. Lebih detail tentang itu di sini.
Pada akhirnya, pendekatan yang lebih baik adalah menanyakan zona waktu mereka kepada pengguna Anda. Berikan pengaturan yang bisa diubah. Anda dapat menggunakan salah satu opsi di atas untuk memilih pengaturan default , tetapi jangan membuatnya mustahil untuk menyimpang dari itu di aplikasi Anda.
Ada juga pendekatan yang sama sekali berbeda dari tidak bergantung pada pengaturan zona waktu komputer pengguna sama sekali. Alih-alih, jika Anda bisa mengumpulkan koordinat garis lintang dan bujur, Anda bisa menyelesaikannya ke zona waktu menggunakan salah satu metode ini . Ini berfungsi baik di perangkat seluler.
Berikut ini adalah solusi JavaScript yang tangguh untuk menentukan zona waktu di mana browser berada.
>>> var timezone = jstz.determine();
>>> timezone.name();
"Europe/London"
https://bitbucket.org/pellepim/jstimezonedetect
Lampiran 1: Sekarang proyek ini terletak di GitHub: https://github.com/pellepim/jstimezonedetect
Ini cara yang lebih lengkap.
Kutipan di bawah ini:
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;
}
Mendapatkan TZ dan DST dari JS (via Way Back Machine)
Africa/Johannesburg
atau Europe/Istanbul
. Lihat wiki tag zona waktu .
Menggunakan pendekatan Unkwntech, saya menulis sebuah fungsi menggunakan jQuery dan PHP. Ini diuji dan berhasil!
Pada halaman PHP tempat Anda ingin memiliki zona waktu sebagai variabel, minta potongan kode ini di suatu tempat dekat bagian atas halaman:
<?php
session_start();
$timezone = $_SESSION['time'];
?>
Ini akan membaca variabel sesi "waktu", yang sekarang akan kita buat.
Pada halaman yang sama, di <head>, Anda harus memasukkan jQuery:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
Juga di <head>, di bawah jQuery, rekatkan ini:
<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>
Anda mungkin atau mungkin tidak memperhatikan, tetapi Anda perlu mengubah URL ke domain Anda yang sebenarnya.
Satu hal terakhir. Anda mungkin bertanya-tanya apa itu timezone.php. Ya begini saja: (buat file baru bernama timezone.php dan arahkan ke sana dengan URL di atas)
<?php
session_start();
$_SESSION['time'] = $_GET['time'];
?>
Jika ini berfungsi dengan benar, pertama-tama akan memuat halaman, menjalankan JavaScript, dan memuat kembali halaman. Anda kemudian dapat membaca variabel $ timezone dan menggunakannya untuk kesenangan Anda! Ini mengembalikan offset zona waktu UTC / GMT saat ini (GMT -7) atau zona waktu apa pun Anda berada.
Untuk mengirim offset zona waktu sebagai header HTTP pada permintaan AJAX dengan jQuery
$.ajaxSetup({
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
}
});
Anda juga dapat melakukan hal serupa untuk mendapatkan nama zona waktu yang sebenarnya dengan menggunakan moment.tz.guess();
dari http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/
Saya masih belum melihat jawaban terperinci di sini yang mendapatkan zona waktu. Anda tidak perlu melakukan geocode berdasarkan alamat IP atau menggunakan PHP (lol) atau menebak secara salah dari offset.
Pertama, zona waktu bukan hanya offset dari GMT. Ini adalah area tanah di mana aturan waktu ditetapkan oleh standar lokal. Beberapa negara memiliki penghematan siang hari, dan akan mengaktifkan DST pada waktu yang berbeda. Biasanya penting untuk mendapatkan zona aktual, bukan hanya offset saat ini.
Jika Anda bermaksud menyimpan zona waktu ini, misalnya dalam preferensi pengguna, Anda menginginkan zona dan bukan hanya offset. Untuk konversi waktu nyata itu tidak masalah.
Sekarang, untuk mendapatkan zona waktu dengan javascript Anda dapat menggunakan ini:
>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.
Namun saya merasa lebih mudah untuk menggunakan plugin yang kuat ini yang mengembalikan zona waktu diformat Olsen:
Dengan PHP date
fungsi Anda akan mendapatkan tanggal waktu server tempat situs tersebut berada. Satu-satunya cara untuk mendapatkan waktu pengguna adalah menggunakan JavaScript.
Tetapi saya menyarankan Anda untuk, jika situs Anda memiliki pendaftaran yang diperlukan maka cara terbaik adalah meminta pengguna sementara untuk memiliki pendaftaran sebagai bidang wajib. Anda dapat membuat daftar berbagai zona waktu di halaman register dan menyimpannya dalam database. Setelah ini, jika pengguna masuk ke situs maka Anda dapat mengatur zona waktu default untuk sesi itu sesuai zona waktu yang dipilih pengguna.
Anda dapat mengatur zona waktu tertentu menggunakan fungsi PHP date_default_timezone_set
. Ini menetapkan zona waktu yang ditentukan untuk pengguna.
Pada dasarnya zona waktu pengguna adalah ke sisi klien, jadi kita harus menggunakan JavaScript untuk ini.
Di bawah ini adalah skrip untuk mendapatkan zona waktu pengguna menggunakan PHP dan 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();
?>
Tetapi sesuai dengan sudut pandang saya, lebih baik bertanya kepada pengguna apakah pendaftaran wajib untuk proyek Anda.
Jangan gunakan alamat IP untuk menentukan lokasi secara definitif (dan karenanya zona waktu) - itu karena dengan NAT, proksi (semakin populer), dan VPN, alamat IP tidak selalu secara realistis mencerminkan lokasi sebenarnya pengguna, tetapi lokasi di mana server yang mengimplementasikan protokol tersebut berada.
Mirip dengan bagaimana kode area AS tidak lagi berguna untuk mencari pengguna telepon, mengingat popularitas portabilitas angka.
Alamat IP dan teknik lain yang ditunjukkan di atas berguna untuk menyarankan default yang dapat disesuaikan / diperbaiki pengguna.
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;
}
Cukup sediakan waktu Anda dalam format cap waktu Unix untuk fungsi ini; JavaScript sudah mengetahui zona waktu pengguna.
Seperti ini:
PHP:
echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';
Ini akan selalu menunjukkan waktu dengan benar berdasarkan zona waktu yang telah ditetapkan pada jam komputernya. Tidak perlu meminta apa pun kepada siapa pun dan menyimpannya di tempat, terima kasih Tuhan!
Mudah, cukup gunakan getTimezoneOffset
fungsi JavaScript seperti ini:
-new Date().getTimezoneOffset()/60;
Tampaknya semua keajaiban ada di
visitortime.getTimezoneOffset()
Itu keren, saya tidak tahu tentang itu. Apakah itu berfungsi di Internet Explorer, dll? Dari sana Anda harus dapat menggunakan JavaScript untuk Ajax, mengatur cookie, apa pun. Saya mungkin akan pergi rute cookie sendiri.
Anda harus mengizinkan pengguna untuk mengubahnya. Kami mencoba menggunakan geolokasi (melalui maxmind) untuk melakukan ini beberapa waktu yang lalu, dan itu cukup sering salah - cukup untuk membuatnya tidak layak dilakukan, jadi kami hanya membiarkan pengguna mengaturnya di profil mereka, dan menunjukkan pemberitahuan kepada pengguna yang belum mengaturnya.
Berikut ini adalah artikel (dengan kode sumber) yang menjelaskan cara menentukan dan menggunakan waktu lokal dalam aplikasi ASP.NET (VB.NET, C #):
Singkatnya, pendekatan yang dijelaskan bergantung pada getTimezoneOffset
fungsi JavaScript , yang mengembalikan nilai yang disimpan dalam cookie sesi dan digunakan oleh kode-belakang untuk menyesuaikan nilai waktu antara GMT dan waktu lokal. Yang menyenangkan adalah bahwa pengguna tidak perlu menentukan zona waktu (kode melakukannya secara otomatis). Ada yang lebih terlibat (ini sebabnya saya menautkan ke artikel), tetapi kode yang disediakan membuatnya sangat mudah digunakan. Saya menduga Anda dapat mengonversi logika ke PHP dan bahasa lain (selama Anda memahami ASP.NET).
Jika Anda menggunakan OpenID untuk otentikasi, Ekstensi Pendaftaran Sederhana akan menyelesaikan masalah bagi pengguna yang diautentikasi (Anda harus mengonversi dari tz ke numerik).
Pilihan lain adalah menyimpulkan zona waktu dari preferensi negara agen pengguna. Ini adalah metode yang agak kasar (tidak akan bekerja untuk en-AS), tetapi membuat perkiraan yang baik.
Sederhana dengan JavaScript dan PHP:
Meskipun pengguna dapat mengacaukan jam internal dan / atau zona waktu, cara terbaik yang saya temukan sejauh ini, untuk mendapatkan offset, tetap ada new Date().getTimezoneOffset();
. Ini non-invasif, tidak membuat kepala pusing dan menghilangkan kebutuhan untuk mengandalkan pihak ketiga.
Katakanlah saya punya tabel users
,, yang berisi bidang date_created int(13)
, untuk menyimpan cap waktu Unix;
Dengan asumsi klien creates a new account
, data yang diterima oleh post
, dan saya perlu insert/update
yang date_created column
dengan klien Unix timestamp, bukan server.
Karena timezoneOffset diperlukan pada saat memasukkan / memperbarui, ia dilewatkan sebagai elemen $ _POST tambahan ketika klien mengirimkan formulir, sehingga menghilangkan kebutuhan untuk menyimpannya dalam sesi dan / atau cookie, dan tidak ada tambahan server yang memukul.
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;
Katakanlah server menerima tzo
sebagai $_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);
Sisipkan / perbarui date_created=$user_timestamp
.
Saat mengambil date_created, Anda dapat mengonversi timestamp seperti:
$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever
Sekarang, contoh ini mungkin sesuai dengan kebutuhan seseorang, ketika harus memasukkan first
stempel waktu ... Ketika datang ke stempel waktu tambahan, atau tabel, Anda mungkin ingin mempertimbangkan memasukkan nilai tzo ke dalam tabel pengguna untuk referensi di masa mendatang, atau mengaturnya sebagai sesi atau sebagai cookie.
PS TAPI bagaimana jika pengguna melakukan perjalanan dan mengganti zona waktu. Masuk pada GMT + 4, bergerak cepat ke GMT-1 dan masuk lagi. Login terakhir akan di masa depan.
Saya pikir ... kami terlalu banyak berpikir.
Anda bisa melakukannya pada klien dengan moment-timezone dan mengirim nilai ke server; penggunaan sampel:
> moment.tz.guess()
"America/Asuncion"
Mendapatkan nama zona waktu TZ Database yang valid dalam PHP adalah proses dua langkah:
Dengan JavaScript, dapatkan offset zona waktu dalam beberapa menit getTimezoneOffset
. Offset ini akan positif jika zona waktu lokal di belakang UTC dan negatif jika berada di depan. Jadi, Anda harus menambahkan tanda berlawanan dengan offset.
var timezone_offset_minutes = new Date().getTimezoneOffset();
timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
Berikan offset ini ke PHP.
Dalam PHP, ubah offset ini menjadi nama zona waktu yang valid dengan fungsi 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>
Saya telah menulis posting blog di atasnya: Cara Mendeteksi Zona Waktu Pengguna di PHP . Ini juga mengandung demo.
Intl.DateTimeFormat().resolvedOptions().timeZone
dan mengirimkannya ke server web. Ref: stackoverflow.com/questions/9772955/…
Cara mudah untuk melakukannya adalah dengan menggunakan:
new Date().getTimezoneOffset();
Salah satu opsi yang mungkin adalah dengan menggunakan Date
bidang header, yang didefinisikan dalam RFC 7231 dan seharusnya mencakup zona waktu. Tentu saja, tidak dijamin bahwa nilainya benar-benar zona waktu klien, tetapi itu bisa menjadi titik awal yang nyaman.
Begini cara saya melakukannya. Ini akan mengatur zona waktu default PHP ke zona waktu lokal pengguna. Cukup rekatkan yang berikut di atas semua halaman Anda:
<?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
?>