Tengo la sospecha de que la Respuesta no da el resultado correcto. En la pregunta, el autor de la pregunta quiere convertir la marca de tiempo del servidor a la hora actual en Hellsinki sin tener en cuenta la zona horaria actual del usuario.
Es el hecho de que la zona horaria del usuario puede ser lo que sea, por lo que no podemos confiar en ella.
Si por ejemplo. La marca de tiempo es 1270544790922 y tenemos una función:
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);
Cuando un neoyorquino visita la página, la alerta (_helsenkiTime) imprime:
Tue Apr 06 2010 05:21:02 GMT-0400 (EDT)
Y cuando un finlandés visita la página, la alerta (_helsenkiTime) imprime:
Tue Apr 06 2010 11:55:50 GMT+0300 (EEST)
Por lo tanto, la función es correcta solo si el visitante de la página tiene la zona horaria objetivo (Europa / Helsinki) en su computadora, pero falla en casi todas las demás partes del mundo. Y debido a que la marca de tiempo del servidor suele ser la marca de tiempo de UNIX, que por definición está en UTC, el número de segundos desde la época de Unix (1 de enero de 1970 a las 00:00:00 GMT), no podemos determinar DST o no DST a partir de la marca de tiempo.
Entonces, la solución es DESCONECTAR la zona horaria actual del usuario e implementar alguna forma de calcular la compensación UTC si la fecha está en DST o no. Javascript no tiene un método nativo para determinar el historial de transición DST de otra zona horaria que la zona horaria actual del usuario. Podemos lograr esto de la manera más simple usando el script del lado del servidor, porque tenemos fácil acceso a la base de datos de la zona horaria del servidor con el historial de transición completo de todas las zonas horarias.
Pero si no tiene acceso a la base de datos de la zona horaria del servidor (o de cualquier otro servidor) Y la marca de tiempo está en UTC, puede obtener una funcionalidad similar codificando las reglas de DST en Javascript.
Para cubrir fechas en los años 1998 - 2099 en Europa / Helsinki, puede utilizar la siguiente función ( 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;
}
Ejemplos de uso:
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);
Y esto imprime lo siguiente independientemente de la zona horaria del usuario:
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
Por supuesto, si puede devolver la marca de tiempo en una forma en la que el desplazamiento (DST o no DST) ya está agregado a la marca de tiempo en el servidor, no tiene que calcularlo en el lado del cliente y puede simplificar mucho la función. PERO recuerde NO usar timezoneOffset (), porque entonces tiene que lidiar con la zona horaria del usuario y este no es el comportamiento deseado.