javascript - gettimezoneoffset - new date() zona horaria
¿Cómo convertir una fecha de JavaScript a UTC? (23)
Supongamos que un usuario de su sitio web ingresa un rango de fechas.
2009-1-1 to 2009-1-3
Debe enviar esta fecha a un servidor para que se procese, pero el servidor espera que todas las fechas y horas estén en UTC.
Ahora supongamos que el usuario está en Alaska o Hawai o Fiji. Dado que se encuentran en una zona horaria muy diferente de UTC, el intervalo de fechas debe convertirse en algo como esto:
2009-1-1T8:00:00 to 2009-1-4T7:59:59
Al usar el objeto Fecha de JavaScript, ¿cómo convertiría el primer intervalo de fechas "localizado" en algo que el servidor entenderá?
El método
toISOString()
devuelve una cadena en formato ISO extendido simplificado ( ISO 8601 ), que siempre tiene una longitud de 24 o 27 caracteres (YYYY-MM-DDTHH:mm:ss.sssZ
o±YYYYYY-MM-DDTHH:mm:ss.sssZ
, respectivamente). La zona horaria es siempre cero desplazamiento UTC, como se indica con el sufijo "Z
".
Fuente: documentos web de MDN
El formato que necesita se crea con el método .toISOString()
. Para los navegadores más antiguos (ie8 y menores), que no son compatibles de forma nativa con este método, el shim puede encontrarse here :
Esto te dará la habilidad de hacer lo que necesitas:
var isoDate = new Date(''yourdatehere'').toISOString();
Para el trabajo en zona horaria, las zonas horarias moment.js y moment.js son herramientas realmente invaluables ... especialmente para navegar en zonas horarias entre el cliente y el servidor javascript.
¿Estás tratando de convertir la fecha en una cadena como esa?
Haría una función para hacer eso y, aunque es un poco controvertido, lo agregaré al prototipo Fecha. Si no te sientes cómodo haciendo eso, entonces puedes ponerlo como una función independiente, pasando la fecha como un parámetro.
Date.prototype.getISOString = function() {
var zone = '''', temp = -this.getTimezoneOffset() / 60 * 100;
if (temp >= 0) zone += "+";
zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;
// "2009-6-4T14:7:32+10:00"
return this.getFullYear() // 2009
+ "-"
+ (this.getMonth() + 1) // 6
+ "-"
+ this.getDate() // 4
+ "T"
+ this.getHours() // 14
+ ":"
+ this.getMinutes() // 7
+ ":"
+ this.getSeconds() // 32
+ zone.substr(0, 3) // +10
+ ":"
+ String(temp).substr(-2) // 00
;
};
Si lo necesitaba en tiempo UTC, simplemente reemplace todas las funciones get * con getUTC *, por ejemplo: getUTCFullYear, getUTCMonth, getUTCHours ... y luego agregue "+00: 00" al final en lugar del desplazamiento de zona horaria del usuario.
Acabo de descubrir que la versión 1.2.3 de date.format.js de Steven Levithan hace exactamente lo que quiero. Le permite proporcionar una cadena de formato para una fecha de JavaScript y se convertirá de la hora local a UTC. Aquí está el código que estoy usando ahora:
// JavaScript dates don''t like hyphens!
var rectifiedDateText = dateText.replace(/-/g, "/");
var d = new Date(rectifiedDateText);
// Using a predefined mask from date.format.js.
var convertedDate = dateFormat(d, ''isoUtcDateTime'');
Aquí está mi método:
var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
El objeto utc
resultante no es realmente una fecha UTC, sino una fecha local desplazada para coincidir con la hora UTC (ver comentarios). Sin embargo, en la práctica hace el trabajo.
Aun mas simple
myvar.setTime(myvar.getTime() + myvar.getTimezoneOffset() * 60000);
En cuanto a su pregunta, queda claro que solo desea enviar el intervalo de fechas a su backend para su posterior procesamiento posterior.
Supongo que usted cumple con las pautas de datos estándar que esperan que los datos estén en un formato particular. Por ejemplo, uso ODATA, que es una API RESTfull que espera que los objetos de fecha y hora estén en el formato:
YYYY-MM-DDT00: 00: 00.
Esto se puede lograr fácilmente a través del fragmento publicado a continuación (Cambie el formato según sus requerimientos).
var mydate;//assuming this is my date object which I want to expose var UTCDateStr = mydate.getUTCFullYear() + "-" + mydate.getUTCMonth() + "-" + mydate.getUTCDate() + "T00:00:00";
Si, por otro lado, estás en mi situación en la que recibiste una fecha de tu backend, y el navegador la convierte a tu fecha local. Por otra parte, si está interesado en la fecha UTC, puede realizar lo siguiente:
var mydate;//assuming this is my date object which I want to expose var UTCDate = new Date(mydate);/*create a copy of your date object. Only needed if you for some reason need the original local date*/ UTCDate.setTime(UTCDate.getTime() + UTCDate.getTimezoneOffset() * 60 * 1000);
El fragmento de código anterior básicamente agrega / resta el tiempo agregado / sustraído por el navegador en función de la zona horaria.
Por ejemplo, si estoy en EST (GMT-5) y mi Servicio devuelve un objeto de fecha y hora = Mié 17 de agosto de 2016 00:00:00 GMT-0500 mi navegador resta automáticamente el desplazamiento de la zona horaria (5hrs) para obtener mi hora local. Entonces, si trato de buscar el tiempo que tengo el miércoles 16 de agosto de 2016 19:00:00 GMT-0500. Esto causa muchos problemas. Hay muchas bibliotecas por ahí que sin duda harán esto más fácil, pero quería compartir el enfoque de JS puro.
Para obtener más información, por favor, visite: http://praveenlobo.com/blog/how-to-convert-javascript-local-date-to-utc-and-utc-to-local-date/ donde en tengo mi inspiración.
¡Espero que esto ayude!
Esta función funciona muy bien para mí.
function ParseDateForSave(dateValue) {
// create a new date object
var newDate = new Date(parseInt(dateValue.substr(6)));
// return the UTC version of the date
return newDate.toISOString();
}
Este método le dará: 2017-08-04T11:15:00.000+04:30
y puede ignorar la variable de zona para simplemente obtener 2017-08-04T11:15:00.000
.
function getLocalIsoDateTime(dtString) {
if(dtString == "")
return "";
var offset = new Date().getTimezoneOffset();
var localISOTime = (new Date(new Date(dtString) - offset * 60000 /*offset in milliseconds*/)).toISOString().slice(0,-1);
//Next two lines can be removed if zone isn''t needed.
var absO = Math.abs(offset);
var zone = (offset < 0 ? "+" : "-") + ("00" + Math.floor(absO / 60)).slice(-2) + ":" + ("00" + (absO % 60)).slice(-2);
return localISOTime + zone;
}
Esto es lo que he hecho en el pasado:
var utcDateString = new Date(new Date().toUTCString()).toISOString();
He encontrado que el análisis de fechas del complemento de globalización de jQuery funciona mejor. Otros métodos tenían problemas con varios navegadores y cosas como date.js no se habían actualizado en mucho tiempo.
Tampoco necesitas un datePicker en la página. Simplemente puede llamar a algo similar al ejemplo dado en la documentación:
$.parseDate(''yy-mm-dd'', ''2007-01-26'');
Los navegadores pueden diferir, y también debe recordar no confiar en ninguna información generada por el cliente, dicho esto, la siguiente declaración funciona para mí (Google Chrome v24 en Mac OS X 10.8.2)
var utcDate = new Date(new Date().getTime());
editar: "¿En qué se diferencia esto de la new Date()
?" Consulte aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
- Si no se proporcionan argumentos, el constructor crea un objeto Fecha de JavaScript para la fecha y hora actual de acuerdo con la configuración del sistema.
- Nota: Cuando se llama a Date como un constructor con más de un argumento, los argumentos específicos representan la hora local. Si se desea UTC, use la nueva Fecha ( Date.UTC(...) ) con los mismos argumentos. (nota: Date.UTC () devuelve el número de milisegundos desde 1970-01-01 00:00:00 UTC)
La adición de 60000 * Date.getTimezoneOffset () como las respuestas anteriores han indicado es incorrecta. Primero, debe pensar que todas las Fechas / Horas ya son UTC con un modificador de zona horaria para fines de visualización.
Una vez más, los navegadores pueden diferir, sin embargo, Date.getTime () devuelve el número de milisegundos desde 1970-01-01 UTC / GMT. Si crea una nueva Fecha utilizando este número como lo hago anteriormente, será UTC / GMT. Sin embargo, si lo muestra llamando a .toString (), aparecerá en su zona horaria local porque .toString () usa su zona horaria local, no la zona horaria del objeto Date al que se llama.
También descubrí que si llama a .getTimezoneOffset () en una fecha, devolverá su zona horaria local, no la zona horaria del objeto de fecha en que lo llamó (no puedo verificar que esto sea estándar).
En mi navegador, al agregar 60000 * Date.getTimezoneOffset () se crea un DateTime que no es UTC . Sin embargo, cuando se muestra dentro de mi navegador (por ejemplo, .toString ()), muestra un DateTime en mi zona horaria local que sería la hora UTC correcta si se ignora la información de la zona horaria.
Mi recomendación al trabajar con fechas es analizar la fecha en campos individuales de la entrada del usuario. Puedes usarlo como una cadena completa, pero estás jugando con fuego.
JavaScript puede tratar dos fechas iguales en diferentes formatos de manera diferente.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
Nunca hagas algo como:
new Date(''date as text'');
Una vez que haya analizado su fecha en sus campos individuales desde la entrada del usuario, cree un objeto de fecha. Una vez que se crea el objeto de fecha, conviértalo a UTC agregando el desplazamiento de zona horaria. No puedo enfatizar lo importante que es usar el desplazamiento desde el objeto de fecha debido a DST (sin embargo, esa es otra discusión para mostrar por qué).
var year = getFullYear(''date as text'');
var month = getMonth(''date as text'');
var dayOfMonth = getDate(''date as text'');
var date = new Date(year, month, dayOfMonth);
var offsetInMs = ((date.getTimezoneOffset() * 60) // Seconds
* 1000); // Milliseconds
var utcDate = new Date(date.getTime + offsetInMs);
Ahora puede pasar la fecha al servidor en hora UTC. De nuevo, recomendaría encarecidamente el uso de cadenas de fecha. Puede pasarlo al servidor desglosado a la granularidad más baja que necesite, por ejemplo, año, mes, día, minuto o como un valor, como milisegundos, desde la época de Unix.
Otra solución para convertir a UTC y mantenerlo como un objeto de fecha: (Funciona al eliminar la parte ''GMT'' del final de la cadena con formato, y luego volver a colocarla en el constructor de la fecha)
var now = new Date();
var now_utc = new Date(now.toUTCString().slice(0, -4));
Necesitaba hacer esto para interactuar con una biblioteca de selector de fecha y hora. Pero en general es una mala idea trabajar con fechas de esta manera.
Los usuarios generalmente desean trabajar con tiempos de datos en su hora local, por lo tanto, o bien actualizan el código del lado del servidor para analizar correctamente las cadenas de datos con desplazamientos, luego convierten a UTC (la mejor opción) o lo convierten en un lado del cliente de la cadena UTC antes de enviarlos a la servidor (como en la respuesta de Will Stern)
Sé que esta pregunta es antigua, pero estaba considerando este mismo problema, y una opción sería enviar date.valueOf () al servidor en su lugar. La función valueOf () de la fecha de javascript envía el número de milisegundos desde la medianoche del 1 de enero de 1970 UTC.
Si estás tratando mucho con las fechas, vale la pena usar moment.js ( http://momentjs.com ). El método para convertir a UTC sería:
moment(yourTime).utc()
Puede usar el formato para cambiar su fecha a cualquier formato que desee:
moment(yourTime).utc().format("YYYY-MM-DD")
También hay opciones de compensación en el momento, pero hay una biblioteca complementaria adicional para tratar la zona horaria ( http://momentjs.com/timezone/ ). La conversión de tiempo sería tan simple como esto:
moment.tz(yourUTCTime, "America/New_York")
Simple y estúpido
var date = new Date();
var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
return new Date(now_utc);
Usando el método UTC de moment.js ;
const moment = require(''moment'');
const utc = moment.utc(new Date(string));
Convertir a ISO sin cambiar la fecha / hora
var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time)
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z
Convertir a ISO con cambio de fecha / hora (la fecha / hora se cambiará)
isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z
Si necesita fecha objeto
Pasar solo la cadena de fecha La fecha supone que la hora se cambia 00:00 por zona horaria:
new Date(''2019-03-11'')
Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)
Si agrega horas y minutos actuales, obtendrá la fecha adecuada:
new Date(''2019-03-11 '' + new Date().getHours() + '':'' + new Date().getMinutes())
Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)
Date.prototype.toUTCArray= function(){
var D= this;
return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),
D.getUTCMinutes(), D.getUTCSeconds()];
}
Date.prototype.toISO= function(){
var tem, A= this.toUTCArray(), i= 0;
A[1]+= 1;
while(i++<7){
tem= A[i];
if(tem<10) A[i]= ''0''+tem;
}
return A.splice(0, 3).join(''-'')+''T''+A.join('':'');
}
date = ''2012-07-28''; stringdate = new Date(date).toISOString();
Debería funcionar en la mayoría de los navegadores más nuevos. devuelve 2012-07-28T00:00:00.000Z
en Firefox 6.0
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();
var userdate = new Date("2009-1-1T8:00:00Z");
var timezone = userdate.getTimezoneOffset();
var serverdate = new Date(userdate.setMinutes(userdate.getMinutes()+parseInt(timezone)));
Esto le dará la fecha y hora UTC adecuadas.
Se debe a que getTimezoneOffset()
le dará la diferencia de zona horaria en minutos. Le recomiendo que no use toISOString()
porque la salida estará en la cadena. Por lo tanto, en el futuro, no podrá manipular la fecha.