Objetivo: Encontrar la "hora local" y la "hora UTC" y construir la URL en el siguiente formato.
Ejemplo de URL: /Actions/Sleep?duration=2002-10-10T12:00:00−05:00
El formato se basa en la recomendación del W3C: http://www.w3.org/TR/xmlschema11-2/#dateTime
La documentación dice:
Por ejemplo, 2002-10-10T12:00:00-05:00 (mediodía del 10 de octubre de 2002, horario central de verano, así como la hora estándar del este en los EE.UU.) es igual a 2002-10-10T17:00:00Z, cinco horas más tarde que 2002-10-10T12:00:00Z.
Así que, según tengo entendido, tengo que encontrar mi hora local mediante new Date() y luego utilizar la función getTimezoneOffset() para calcular la diferencia y luego adjuntarla al final de la cadena.
1.Obtener la hora local con el formato
var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)
Salida
2013-07-02T09:00:00
2.Obtener el desfase horario UTC por hora
var offset = local.getTimezoneOffset() / 60;
Salida
7
3.Construir URL (sólo parte del tiempo)
var duration = local + "-" + offset + ":00";
salida:
2013-07-02T09:00:00-7:00
La salida anterior significa que mi hora local es 2013/07/02 9am y la diferencia con UTC es de 7 horas (UTC es de 7 horas por delante de la hora local)
Hasta ahora parece funcionar, pero ¿qué pasa si getTimezoneOffset() devuelve un valor negativo como -120?.
Me pregunto cómo debería ser el formato en tal caso porque no puedo deducirlo del documento W3C. Gracias de antemano.
Lo siguiente debería funcionar correctamente, y para todos los navegadores (gracias a @MattJohnson por el consejo)
begin snippet: js hide: false console: true babel: false -->
Date.prototype.toIsoString = function() {
var tzo = -this.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
var norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return this.getFullYear() +
'-' + pad(this.getMonth() + 1) +
'-' + pad(this.getDate()) +
'T' + pad(this.getHours()) +
':' + pad(this.getMinutes()) +
':' + pad(this.getSeconds()) +
dif + pad(tzo / 60) +
':' + pad(tzo % 60);
}
var dt = new Date();
console.log(dt.toIsoString());
La función getTimezoneOffset()
devuelve el signo opuesto al formato requerido por la especificación a la que has hecho referencia.
Este formato es también conocido como ISO8601, o más precisamente como RFC3339.
En este formato, UTC se representa con una Z
mientras que todos los demás formatos se representan con un desfase respecto a UTC. El significado es el mismo que el de JavaScript's, pero se invierte el orden de la resta, por lo que el resultado lleva el signo contrario.
Además, no hay ningún método en el objeto nativo Date
llamado format
, así que tu función en #1 fallará a menos que estés usando una librería para conseguirlo. Consulte esta documentación.
Si estás buscando una librería que pueda trabajar con este formato directamente, te recomiendo que pruebes moment.js. De hecho, este es el formato por defecto, así que puedes simplemente hacerlo:
var m = moment(); // get "now" as a moment
var s = m.format(); // the ISO format is the default so no parameters are needed
// sample output: 2013-07-01T17:55:13-07:00
Esta es una solución bien probada, cross-browser, y tiene muchas otras características útiles.
Esta es mi función para la zona horaria de los clientes, es ligera y sencilla
function getCurrentDateTimeMySql() {
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
var mySqlDT = localISOTime;
return mySqlDT;
}