Tôi muốn máy chủ luôn phục vụ ngày trong UTC trong HTML và có JavaScript trên trang web của khách hàng chuyển đổi nó thành múi giờ địa phương của người dùng.
Tiền thưởng nếu tôi có thể xuất ra ở định dạng ngày địa phương của người dùng.
Có vẻ cách dễ nhất để bắt đầu với ngày UTC là tạo một đối tượng Date
mới và sử dụng các phương thức setUTC…
để đặt ngày/giờ bạn muốn.
Sau đó, các phương thức toLocale…String
khác nhau sẽ cung cấp đầu ra cục bộ.
// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);
console.log(d); // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString()); // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString()); // -> 02/28/2004
console.log(d.toLocaleTimeString()); // -> 23:45:26
Câu hỏi này khá cũ, vì vậy khoảnh khắc.js không tồn tại vào thời điểm đó, nhưng đối với các dự án mới, nó đơn giản hóa rất nhiều nhiệm vụ như thế này rất nhiều.
Tốt nhất là phân tích chuỗi ngày của bạn từ UTC như sau (tạo chuỗi ISO-8601 tương thích trên máy chủ để có kết quả nhất quán trên tất cả các trình duyệt):
var m = moment("2013-02-08T09:30:26Z");
Bây giờ chỉ cần sử dụng m
trong ứng dụng của bạn, khoảnh khắc mặc định là múi giờ cục bộ cho các hoạt động hiển thị. Có nhiều cách để định dạng các giá trị ngày và thời gian hoặc trích xuất các phần của nó.
Bạn thậm chí có thể định dạng một đối tượng khoảnh khắc trong ngôn ngữ người dùng như thế này:
m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us
Để chuyển đổi một đối tượng Moment.js thành một múi giờ khác (nghĩa là không phải cục bộ cũng như UTC), bạn sẽ cần tiện ích mở rộng múi giờ khoảnh khắc.js . Trang đó cũng có một số ví dụ, nó khá đơn giản để sử dụng.
Bạn có thể sử dụng new Date().getTimezoneOffset()/60
cho múi giờ. Ngoài ra còn có một phương thức toLocaleString()
để hiển thị một ngày bằng cách sử dụng ngôn ngữ của người dùng.
Đây là toàn bộ danh sách: Làm việc với Ngày
Khi bạn đã xây dựng đối tượng ngày của mình, đây là đoạn trích cho chuyển đổi:
Hàm lấy một đối tượng Ngày định dạng UTC và chuỗi định dạng.
Bạn sẽ cần một nguyên mẫu Date.strftime
.
function UTCToLocalTimeString(d, format) {
if (timeOffsetInHours == null) {
timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
}
d.setHours(d.getHours() + timeOffsetInHours);
return d.strftime(format);
}
Đây là những gì tôi đã sử dụng trong các dự án trước đây:
var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set. again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
Trong JS, không có cách đơn giản và đa nền tảng nào để định dạng thời gian ngày cục bộ, ngoài việc chuyển đổi từng thuộc tính như đã đề cập ở trên.
Đây là một bản hack nhanh mà tôi sử dụng để lấy YYYY-MM-DD cục bộ. Lưu ý rằng đây là một hack, vì ngày cuối cùng sẽ không có múi giờ chính xác nữa (vì vậy bạn phải bỏ qua múi giờ). Nếu tôi cần bất cứ điều gì khác, tôi sử dụng khoảnh khắc.
var d = new Date();
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0);
// 2017-05-09T08:24:26.581Z (but this is not UTC)
D.getTimezone Offerset () trả về độ lệch múi giờ tính bằng phút và d.getTime () tính bằng ms, do đó x 60.000.
Phương thức .getTimezoneOffset()
báo cáo độ lệch múi giờ tính bằng phút, tính "hướng tây" từ múi giờ GMT/UTC, dẫn đến giá trị bù âm so với giá trị thường được sử dụng. (Ví dụ: thời gian ở New York sẽ được báo cáo là +240 phút hoặc +4 giờ)
Để có được độ lệch múi giờ bình thường tính bằng giờ, bạn cần sử dụng:
var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60
Chi tiết quan trọng:
Lưu ý rằng thời gian tiết kiệm ánh sáng ban ngày được tính vào kết quả - vì vậy những gì phương pháp này mang lại cho bạn thực sự là thời gian bù - không phải là địa lý thực tế múi giờ bù.
Với ngày từ mã PHP tôi đã sử dụng một cái gì đó như thế này ..
function getLocalDate(php_date) {
var dt = new Date(php_date);
var minutes = dt.getTimezoneOffset();
dt = new Date(dt.getTime() + minutes*60000);
return dt;
}
Chúng ta có thể gọi nó như thế này
var localdateObj = getLocalDate('2015-09-25T02:57:46');
Tôi trộn các câu trả lời cho đến nay và thêm vào đó, bởi vì tôi phải đọc tất cả chúng và điều tra thêm một lúc để hiển thị chuỗi thời gian ngày từ db theo định dạng múi giờ cục bộ của người dùng.
Chuỗi datetime đến từ một python/Django db ở định dạng: 2016-12-05T15: 12: 24.215Z
Phát hiện đáng tin cậy ngôn ngữ trình duyệt trong JavaScript dường như không hoạt động trong tất cả các trình duyệt (xem JavaScript để phát hiện tùy chọn ngôn ngữ trình duyệt ), vì vậy tôi nhận ngôn ngữ trình duyệt từ máy chủ.
Python/Django: gửi yêu cầu ngôn ngữ trình duyệt dưới dạng tham số ngữ cảnh:
language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })
HTML: viết nó trong một đầu vào ẩn:
<input type="hidden" id="browserlanguage" value={{ language }}/>
JavaScript: nhận giá trị của đầu vào ẩn, ví dụ: en-GB, en-US; q = 0.8, en; q = 0.6/và sau đó chỉ sử dụng ngôn ngữ đầu tiên trong danh sách thông qua biểu thức thay thế và biểu thức chính quy
const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");
JavaScript: chuyển đổi thành datetime và định dạng nó:
var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);
Kết quả là (ngôn ngữ trình duyệt là en-gb): 05/12/2016, 14:58
Giải pháp tốt nhất tôi gặp phải là tạo các thẻ [time display = "llll" datetime = "UTC TIME" /] và sử dụng javascript (jquery) để phân tích và hiển thị nó theo thời gian của người dùng.
http://momentjs.com/ Moment.js
sẽ hiển thị thời gian độc đáo.
Bạn có thể sử dụng thông tin sau, báo cáo thời gian bù từ GMT theo phút:
new Date().getTimezoneOffset();
Chú thích : - hàm này trả về một số âm.
getTimeZone Offerset () và toLocaleString phù hợp với công việc ngày cơ bản, nhưng nếu bạn cần hỗ trợ múi giờ thực, hãy xem mde's TimeZone.js .
Có một vài lựa chọn khác được thảo luận trong câu trả lời cho câu hỏi này
Để chuyển đổi ngày thành ngày cục bộ, hãy sử dụng phương thức toLocaleDateString ().
var date = (new Date(str)).toLocaleDateString(defaultlang, options);
Để chuyển đổi thời gian thành giờ địa phương, hãy sử dụng phương thức toLocaleTimeString ().
var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;
var clientDateStr = userDate.toLocaleString(locale, {
year: 'numeric',
month: 'numeric',
day: 'numeric'
});
var clientDateTimeStr = userDate.toLocaleString(locale, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
});
console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);