У мене є підозра, що відповідь не дає правильного результату. У запитанні запитувач хоче перетворити часову позначку з сервера на поточний час у Hellsinki, не зважаючи на поточний часовий пояс користувача.
Справа в тому, що часовий пояс користувача може бути будь-коли, тому ми не можемо йому довіряти.
Якщо напр. часова мітка - 1270544790922, і у нас є функція:
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);
Коли нью-йоркський відвідувач переходить на сторінку, сповіщення (_helsenkiTime) друкує:
Tue Apr 06 2010 05:21:02 GMT-0400 (EDT)
А коли Finlander відвідує сторінку, попередження (_helsenkiTime) друкує:
Tue Apr 06 2010 11:55:50 GMT+0300 (EEST)
Таким чином, ця функція є правильною лише в тому випадку, якщо відвідувач сторінки має на своєму комп’ютері цільовий часовий пояс (Європа / Гельсінкі), але не спрацьовує майже у всіх інших частинах світу. Оскільки часова мітка сервера зазвичай є часовою міткою UNIX, яка за визначенням є в UTC, кількість секунд з часу епохи Unix (1 січня 1970 00:00:00 GMT), ми не можемо визначити DST або non-DST від часової мітки.
Таким чином, рішення полягає у відхиленні поточного часового поясу користувача та застосуванні певного способу обчислення зміщення UTC за датою, чи є дата у DST чи ні. Javascript не має власного методу для визначення історії переходу DST іншого часового поясу, ніж поточний часовий пояс користувача. Цього ми можемо досягти найбільш просто за допомогою серверного скрипту, оскільки у нас є легкий доступ до бази даних часових поясів сервера з усією історією переходу всіх часових поясів.
Але якщо у вас немає доступу до бази даних часових поясів сервера (або будь-якого іншого сервера) І часова мітка знаходиться в UTC, ви можете отримати подібну функціональність, жорстко кодуючи правила DST у Javascript.
Для висвітлення дат у 1998 - 2099 роках у Європі / Гельсінкі ви можете використовувати таку функцію ( 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;
}
Приклади використання:
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);
І це друкується наступне незалежно від часового поясу користувача:
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
Звичайно, якщо ви можете повернути часову позначку у формі, що зміщення (DST або не-DST) вже додане до часової позначки на сервері, вам не доведеться розраховувати його на стороні клієнтів і ви можете значно спростити функцію. Але НЕ пам'ятайте, щоб НЕ використовувати timezoneOffset (), оскільки тоді вам доведеться мати справу з часовим поясом користувача, і це не бажана поведінка.