Có cách nào đáng tin cậy để lấy múi giờ từ trình duyệt của khách hàng không? Tôi thấy các liên kết sau đây nhưng tôi muốn một giải pháp mạnh mẽ hơn.
Có cách nào đáng tin cậy để lấy múi giờ từ trình duyệt của khách hàng không? Tôi thấy các liên kết sau đây nhưng tôi muốn một giải pháp mạnh mẽ hơn.
Câu trả lời:
Nhìn vào kho lưu trữ này pageloom nó là hữu ích
tải xuống jstz.min.js và thêm chức năng vào trang html của bạn
<script language="javascript">
function getTimezoneName() {
timezone = jstz.determine()
return timezone.name();
}
</script>
và gọi chức năng này từ thẻ hiển thị của bạn
Intl.DateTimeFormat().resolvedOptions().timeZone
(không có IE11) theo đề xuất của Wallace.
Nửa thập kỷ sau, chúng tôi có cách tích hợp sẵn cho nó! Đối với các trình duyệt hiện đại, tôi sẽ sử dụng:
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);
Điều này trả về chuỗi múi giờ IANA, nhưng không phải là phần bù . Tìm hiểu thêm tại tài liệu tham khảo MDN .
Bảng tương thích - tính đến tháng 3 năm 2019, hoạt động cho 90% trình duyệt được sử dụng trên toàn cầu. Không hoạt động trên Internet Explorer .
Intl.DateTimeFormat().resolvedOptions().timeZone
->undefined
Intl.DateTimeFormat().resolvedOptions().timeZone
sẽ trả về giá trị mong đợi bắt đầu từ Firefox 52: kangax.github.io/compat-table/esintl/ mẹo
Thông thường khi mọi người đang tìm kiếm "múi giờ", cái sẽ đủ chỉ là "bù UTC". ví dụ: máy chủ của họ ở trong UTC + 5 và họ muốn biết rằng máy khách của họ đang chạy trong UTC-8 .
Trong javascript cũ đơn giản (new Date()).getTimezoneOffset()/60
sẽ trả về số giờ hiện tại được bù từ UTC.
Đáng chú ý là một "gotcha" có thể có trong dấu hiệu của getTimezoneOffset()
giá trị trả về (từ tài liệu MDN) :
Độ lệch múi giờ là chênh lệch, tính bằng phút, giữa UTC và giờ địa phương. Lưu ý rằng điều này có nghĩa là phần bù là dương nếu múi giờ địa phương đứng sau UTC và âm nếu nó ở phía trước. Ví dụ: đối với múi giờ UTC + 10: 00 (Giờ chuẩn miền đông Úc, Giờ Vladivostok, Giờ chuẩn Chamorro), -600 sẽ được trả về.
Tuy nhiên, tôi khuyên bạn nên sử dụng day.js cho mã Javascript liên quan đến thời gian / ngày. Trong trường hợp đó, bạn có thể nhận được bù UTC được định dạng ISO 8601 bằng cách chạy:
> dayjs().format("Z")
"-08:00"
Có lẽ gấu đề cập rằng khách hàng có thể dễ dàng làm sai lệch thông tin này.
(Lưu ý: câu trả lời này ban đầu được đề xuất https://momentjs.com/ , nhưng dayjs là một lựa chọn hiện đại hơn, nhỏ hơn.)
Hiện tại, đặt cược tốt nhất có lẽ là jstz như được đề xuất trong câu trả lời của mbayloon .
Để hoàn thiện, cần đề cập rằng có một tiêu chuẩn theo cách của nó: Intl . Bạn có thể thấy điều này trong Chrome rồi:
> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"
(Điều này không thực sự tuân theo tiêu chuẩn, đó là một lý do nữa để gắn bó với thư viện)
Intl
có nghĩa vụ phải trả undefined
cho các timeZone
thuộc tính nếu bạn không tự xác định một múi giờ trong xây dựng DateTimeFormat
. Thay vào đó, Chrome lệch khỏi tiêu chuẩn bằng cách trả lại múi giờ của hệ thống; đó là những gì câu trả lời của Julian khai thác, nhưng cũng là lý do tại sao ông nói "không thực sự tuân theo tiêu chuẩn".
bạn có thể sử dụng múi giờ để đoán múi giờ:
> moment.tz.guess()
"America/Asuncion"
Đây là một jsfiddle
Nó cung cấp tên viết tắt của múi giờ người dùng hiện tại.
Đây là mẫu mã
var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));
May 22 2015 03:45 PM CDT
tôi đã sử dụng console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
Tôi đã sử dụng một cách tiếp cận tương tự như phương pháp của Josh Fraser , phương pháp này xác định thời gian bù của trình duyệt từ UTC và liệu nó có nhận ra DST hay không (nhưng phần nào được đơn giản hóa từ mã của anh ấy):
var ClientTZ = {
UTCoffset: 0, // Browser time offset from UTC in minutes
UTCoffsetT: '+0000S', // Browser time offset from UTC in '±hhmmD' form
hasDST: false, // Browser time observes DST
// Determine browser's timezone and DST
getBrowserTZ: function () {
var self = ClientTZ;
// Determine UTC time offset
var now = new Date();
var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0); // Jan
var diff1 = -date1.getTimezoneOffset();
self.UTCoffset = diff1;
// Determine DST use
var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0); // Jun
var diff2 = -date2.getTimezoneOffset();
if (diff1 != diff2) {
self.hasDST = true;
if (diff1 - diff2 >= 0)
self.UTCoffset = diff2; // East of GMT
}
// Convert UTC offset to ±hhmmD form
diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
var hr = Math.floor(diff2);
var min = diff2 - hr;
diff2 = hr * 100 + min * 60;
self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');
return self.UTCoffset;
}
};
// Onload
ClientTZ.getBrowserTZ();
Khi tải, ClientTZ.getBrowserTZ()
hàm được thực thi, sẽ thiết lập:
ClientTZ.UTCoffset
để bù thời gian của trình duyệt từ UTC tính bằng phút (ví dụ: CST là −360 phút, tức là −6,0 giờ so với UTC);ClientTZ.UTCoffsetT
đến phần bù ở dạng '±hhmmD'
(ví dụ '-0600D'
:), trong đó hậu tố D
dành cho DST và S
cho tiêu chuẩn (không phải DST);ClientTZ.hasDST
(thành đúng hoặc sai).Việc ClientTZ.UTCoffset
này được cung cấp trong vài phút thay vì hàng giờ, bởi vì một số múi giờ có độ lệch hàng giờ (ví dụ: +0415).
Mục đích đằng sau ClientTZ.UTCoffsetT
là sử dụng nó làm chìa khóa vào bảng múi giờ (không được cung cấp ở đây), chẳng hạn như cho <select>
danh sách thả xuống .
7-1
cho tháng 7 thay vì tháng 6. Tôi không chắc liệu nó có thực sự tạo nên sự khác biệt hay không, vì tôi nghi ngờ có những kế hoạch DST khu vực không bao gồm tháng Sáu.
Không. Không có cách đáng tin cậy duy nhất và sẽ không bao giờ có. Bạn có thực sự nghĩ rằng bạn có thể tin tưởng khách hàng?