Tôi có một nghi ngờ, rằng Câu trả lời không cho kết quả chính xác. Trong câu hỏi, người hỏi muốn chuyển đổi dấu thời gian từ máy chủ sang thời gian hiện tại ở Hellsinki bất kể múi giờ hiện tại của người dùng.
Thực tế là múi giờ của người dùng có thể là múi giờ nên chúng tôi không thể tin tưởng vào nó.
Nếu vd. dấu thời gian là 1270544790922 và chúng ta có một hàm:
var _date = new Date();
_date.setTime(1270544790922);
var _helsenkiOffset = 2*60*60;//maybe 3
var _userOffset = _date.getTimezoneOffset()*60*60;
var _helsenkiTime = new Date(_date.getTime()+_helsenkiOffset+_userOffset);
Khi một người New York truy cập trang, cảnh báo (_helsenkiTime) sẽ in:
Tue Apr 06 2010 05:21:02 GMT-0400 (EDT)
Và khi một người Phần Lan truy cập trang, cảnh báo (_helsenkiTime) sẽ in:
Tue Apr 06 2010 11:55:50 GMT+0300 (EEST)
Vì vậy, chức năng chỉ đúng nếu khách truy cập trang có múi giờ mục tiêu (Châu Âu / Helsinki) trong máy tính của anh ta, nhưng không thành công ở hầu hết các nơi khác trên thế giới. Và bởi vì dấu thời gian của máy chủ thường là dấu thời gian UNIX, theo định nghĩa là UTC, số giây kể từ Kỷ nguyên Unix (ngày 1 tháng 1 năm 1970 00:00:00 GMT), chúng tôi không thể xác định DST hoặc không phải DST từ dấu thời gian.
Vì vậy, giải pháp là XÓA múi giờ hiện tại của người dùng và thực hiện một số cách để tính toán bù UTC cho dù ngày đó có ở DST hay không. Javascript không có phương pháp gốc để xác định lịch sử chuyển đổi DST của múi giờ khác với múi giờ hiện tại của người dùng. Chúng tôi có thể đạt được điều này đơn giản nhất bằng cách sử dụng tập lệnh phía máy chủ, vì chúng tôi có thể dễ dàng truy cập vào cơ sở dữ liệu múi giờ của máy chủ với toàn bộ lịch sử chuyển đổi của tất cả các múi giờ.
Nhưng nếu bạn không có quyền truy cập vào cơ sở dữ liệu múi giờ của máy chủ (hoặc bất kỳ máy chủ nào khác) VÀ dấu thời gian ở UTC, bạn có thể có được chức năng tương tự bằng cách mã hóa cứng các quy tắc DST trong Javascript.
Để hiển thị các ngày trong năm 1998 - 2099 ở Châu Âu / Helsinki, bạn có thể sử dụng hàm sau ( jsfiddled ):
function timestampToHellsinki(server_timestamp) {
function pad(num) {
num = num.toString();
if (num.length == 1) return "0" + num;
return num;
}
var _date = new Date();
_date.setTime(server_timestamp);
var _year = _date.getUTCFullYear();
// Return false, if DST rules have been different than nowadays:
if (_year<=1998 && _year>2099) return false;
// Calculate DST start day, it is the last sunday of March
var start_day = (31 - ((((5 * _year) / 4) + 4) % 7));
var SUMMER_start = new Date(Date.UTC(_year, 2, start_day, 1, 0, 0));
// Calculate DST end day, it is the last sunday of October
var end_day = (31 - ((((5 * _year) / 4) + 1) % 7))
var SUMMER_end = new Date(Date.UTC(_year, 9, end_day, 1, 0, 0));
// Check if the time is between SUMMER_start and SUMMER_end
// If the time is in summer, the offset is 2 hours
// else offset is 3 hours
var hellsinkiOffset = 2 * 60 * 60 * 1000;
if (_date > SUMMER_start && _date < SUMMER_end) hellsinkiOffset =
3 * 60 * 60 * 1000;
// Add server timestamp to midnight January 1, 1970
// Add Hellsinki offset to that
_date.setTime(server_timestamp + hellsinkiOffset);
var hellsinkiTime = pad(_date.getUTCDate()) + "." +
pad(_date.getUTCMonth()) + "." + _date.getUTCFullYear() +
" " + pad(_date.getUTCHours()) + ":" +
pad(_date.getUTCMinutes()) + ":" + pad(_date.getUTCSeconds());
return hellsinkiTime;
}
Ví dụ về cách sử dụng:
var server_timestamp = 1270544790922;
document.getElementById("time").innerHTML = "The timestamp " +
server_timestamp + " is in Hellsinki " +
timestampToHellsinki(server_timestamp);
server_timestamp = 1349841923 * 1000;
document.getElementById("time").innerHTML += "<br><br>The timestamp " +
server_timestamp + " is in Hellsinki " + timestampToHellsinki(server_timestamp);
var now = new Date();
server_timestamp = now.getTime();
document.getElementById("time").innerHTML += "<br><br>The timestamp is now " +
server_timestamp + " and the current local time in Hellsinki is " +
timestampToHellsinki(server_timestamp);
Và điều này sẽ in như sau bất kể múi giờ của người dùng:
The timestamp 1270544790922 is in Hellsinki 06.03.2010 12:06:30
The timestamp 1349841923000 is in Hellsinki 10.09.2012 07:05:23
The timestamp is now 1349853751034 and the current local time in Hellsinki is 10.09.2012 10:22:31
Tất nhiên nếu bạn có thể trả về dấu thời gian ở dạng mà phần bù (DST hoặc không phải DST) đã được thêm vào dấu thời gian trên máy chủ, bạn không phải tính toán nó ở phía máy khách và bạn có thể đơn giản hóa hàm rất nhiều. NHƯNG nhớ KHÔNG sử dụng timezoneOffset (), vì khi đó bạn phải xử lý múi giờ của người dùng và đây không phải là hành vi mong muốn.