Mostrar fecha / hora en formato de usuario y desplazamiento de hora

167

Quiero que el servidor siempre sirva fechas en UTC en el HTML, y que JavaScript en el sitio del cliente lo convierta a la zona horaria local del usuario.

Bonificación si puedo mostrar en el formato de fecha de configuración regional del usuario.

kch
fuente

Respuestas:

165

Parece que la forma más infalible de comenzar con una fecha UTC es crear un nuevo Dateobjeto y usar los setUTC…métodos para establecerlo en la fecha / hora que desee.

Luego, los diversos toLocale…Stringmétodos proporcionarán resultados localizados.

Ejemplo:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

Algunas referencias:

kch
fuente
1
En Firefox, toLocateDateString()devuelve algo que se parece a 'Domingo 12 de enero de 2014' ..
BlueRaja - Danny Pflughoeft
1
Hmm, sí, es un problema bastante serio. El uso de estos métodos no funcionará si desea que la fecha se vea igual en todos los navegadores. ¿Alguna alternativa conocida?
Josh Mc
66
Versión de una línea de la inicialización anterior:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael
44
Puede valer la pena considerar que Chrome (a partir de v35) no tiene en cuenta la configuración regional del usuario en las toLocaleString()funciones.
benno
8
Lo siento, pero este método no funciona en (Estoy en Australia), cuando ejecuto el código anterior, la fecha se muestra en formato estadounidense. Además, MDN dice que "la configuración regional utilizada y la forma de la cadena devuelta dependen completamente de la implementación".
tgrrr
65

Para nuevos proyectos, solo use moment.js

Esta pregunta es bastante antigua, por lo que moment.js no existía en ese momento, pero para proyectos nuevos, simplifica mucho tareas como esta.

Es mejor analizar su cadena de fecha desde UTC de la siguiente manera (cree una cadena compatible con ISO-8601 en el servidor para obtener resultados consistentes en todos los navegadores):

var m = moment("2013-02-08T09:30:26Z");

Ahora solo use men su aplicación, moment.js por defecto es la zona horaria local para las operaciones de visualización. Hay muchas formas de formatear los valores de fecha y hora o extraer partes de ellos.

Incluso puede formatear un objeto de momento en la configuración regional de los usuarios de esta manera:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

Para transformar un objeto moment.js en una zona horaria diferente (es decir, ni local ni UTC), necesitará la extensión de zona horaria moment.js . Esa página también tiene algunos ejemplos, es bastante simple de usar.

theDmi
fuente
¿Cómo combinas todo esto? m.utcOffset (offset) .format ('LLL') no parece funcionar.
Bart
¿Debería Luxon o Day.js ser la biblioteca sugerida ahora?
Homero
1
Sugiero agregarFor old projects, just use jQuery
Xenos
No funciona en Chrome - todavía muestra AM / PM a pesar de que el tiempo está ajustado a las 24h en la configuración regional de la computadora
vir nos
20

Puedes usar new Date().getTimezoneOffset()/60para la zona horaria. También hay un toLocaleString()método para mostrar una fecha usando la configuración regional del usuario.

Aquí está la lista completa: trabajar con fechas

jop
fuente
toLocaleString es extremadamente poco confiable para presentar fechas en el formato que un usuario podría esperar. Incluso cuando se admite ISO 402, sigue siendo poco confiable y basa el formato en un idioma, no en un entorno local.
RobG
@RobG, ¿cuál es la solución en lugar de toLocaleString?
usuario924
@ user924: puede usar una biblioteca, hay muchas para elegir. El problema con toLocaleString es que diferentes implementaciones dan diferentes resultados con diferentes niveles de soporte para varios idiomas y regiones. Por ejemplo, el idioma predeterminado de mi sistema no es en EE. UU., Pero el formato predeterminado para toLocaleString para algunos navegadores es el formato de EE. UU., Otros respetan el idioma de mi sistema. Es lo mismo con los nombres de zonas horarias, solo que peor, ya que no están estandarizados en absoluto. :-(
RobG
7

Una vez que haya construido su objeto de fecha, aquí hay un fragmento para la conversión:

La función toma un objeto de fecha con formato UTC y una cadena de formato.
Necesitarás un Date.strftimeprototipo.

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}
simianarmy
fuente
66
de donde saliste el tiempo?
Anuj Pandey
¿Establecer las horas tiene algún efecto en las partes Día / Fecha / Año de un objeto Fecha? No parece
ChristoKiwi
1
@ ChristoKiwi: se espera que el valor pasado a setHours sea ​​un número entero que getTimezoneOffset()/60puede devolver una fracción (por ejemplo, un desplazamiento de India de +05: 30 devolverá 5.5). Los decimales se truncan. De lo contrario, establecer las horas actualiza otros valores (configure las horas en 48 y vea qué sucede).
RobG
7

En JS no hay formas simples y multiplataforma para formatear la hora local, además de convertir cada propiedad como se mencionó anteriormente.

Aquí hay un truco rápido que uso para obtener el YYYY-MM-DD local. Tenga en cuenta que este es un truco, ya que la fecha final ya no tendrá la zona horaria correcta (por lo que debe ignorar la zona horaria). Si necesito algo más, uso moment.js.

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

D.getTimezoneOffset () devuelve el desplazamiento de zona horaria en minutos, y d.getTime () está en ms, por lo tanto, x 60,000.

Jeremy Chone
fuente
1
@VG Agregué más información sobre de dónde viene el 60k. Espero que esto ayude.
Jeremy Chone
5

Esto es lo que he usado en proyectos anteriores:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
marca
fuente
44
Esto es con cosas específicas de ASP.NET.
ZiggyTheHamster
Las compensaciones de zona horaria no son necesariamente múltiplos de una hora, por getTimezoneOffset()/60lo que a menudo devuelven un valor decimal. Esto es particularmente cierto para fechas anteriores a 1900, donde muchos lugares tenían compensaciones en minutos y segundos. Además, ahora se requieren fechas de JavaScript para admitir compensaciones históricas. Por ejemplo, en 1890, la compensación en Moscú fue de +2: 30: 17. Consulte Navegadores, zonas horarias, error de Chrome 67 .
RobG
3

El .getTimezoneOffset()método informa el desplazamiento de la zona horaria en minutos, contando "hacia el oeste" desde la zona horaria GMT / UTC, lo que resulta en un valor de compensación que es negativo a lo que uno está habitualmente acostumbrado. (Por ejemplo, el tiempo de Nueva York sería de +240 minutos o +4 horas)

Para obtener un desplazamiento de zona horaria normal en horas, debe usar:

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

Detalles importantes:
tenga en cuenta que el horario de verano se tiene en cuenta en el resultado, por lo que este método le proporciona realmente el desplazamiento de tiempo , no el desplazamiento de zona horaria geográfica real .

Már Örlygsson
fuente
3

Con la fecha del código PHP usé algo como esto ...

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

Podemos llamarlo así

var localdateObj = getLocalDate('2015-09-25T02:57:46');
hriziya
fuente
La pregunta era sobre JavaScript, no PHP.
pipedreambomb
55
La respuesta está solo en JavaScript. Se menciona en la pregunta que la fecha del servidor está en UTC. entonces el servidor podría estar en cualquier idioma. así que respondí solo para PHP
hriziya
3

Mezclo las respuestas hasta ahora y las agrego, porque tuve que leerlas todas e investigar adicionalmente durante un tiempo para mostrar una cadena de fecha y hora de db en el formato de zona horaria local de un usuario.

La cadena de fecha y hora proviene de una base de datos python / django en el formato: 2016-12-05T15: 12: 24.215Z

La detección confiable del idioma del navegador en JavaScript no parece funcionar en todos los navegadores (consulte JavaScript para detectar la preferencia de idioma del navegador ), por lo que obtengo el idioma del navegador del servidor.

Python / Django: envíe el idioma del navegador de solicitud como parámetro de contexto:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML: escríbelo en una entrada oculta:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript: obtenga el valor de la entrada oculta, por ejemplo, en-GB, en-US; q = 0.8, en; q = 0.6 / y luego tome el primer idioma de la lista solo mediante reemplazo y expresión regular

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript: convertir a fecha y hora y formatearlo:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

Ver: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

El resultado es (el idioma del navegador es en-gb): 12/05/2016, 14:58

Anja
fuente
3

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);

Sergey
fuente
Para la referencia: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… (necesitaba la optionsparte para mi caso)
Xenos
2

La mejor solución que he encontrado es crear etiquetas [time display = "llll" datetime = "UTC TIME" /], y usar javascript (jquery) para analizar y mostrar en relación con la hora del usuario.

http://momentjs.com/ Moment.js

mostrará la hora muy bien.

Daniel
fuente
2

Puede usar lo siguiente, que informa el desplazamiento de la zona horaria de GMT en minutos:

new Date().getTimezoneOffset();

Nota: esta función devuelve un número negativo.

Dave
fuente
1

getTimeZoneOffset () y toLocaleString son buenos para el trabajo básico de fechas, pero si necesita soporte de zona horaria real, mire TimeZone.js de mde .

Hay algunas opciones más discutidas en la respuesta a esta pregunta

Eón
fuente
1

Para convertir la fecha a la fecha local, use el métodoLocaleDateString ().

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

Para convertir la hora a la hora local, use el método toLocaleTimeString ().

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
Codemaker
fuente
-12

No sé cómo hacer la configuración regional, pero JavaScript es una tecnología del lado del cliente.

usersLocalTime = new Date();

tendrá la hora y la fecha del cliente (según lo informado por su navegador y, por extensión, la computadora en la que están sentados). Debería ser trivial incluir el tiempo del servidor en la respuesta y hacer algunos cálculos matemáticos simples para adivinar la compensación de tiempo.

japollock
fuente