Obtener moment.js para mostrar fechas y horas apropiadas para la información que se está viendo

Previous answers on here pointed me to momento.js for javascript date handling and I am really happy to find it. I can parse and manipulate quite happily.

The users on my website look at info relating to diverse physical sites/locations, and I want to show associated datetimes in the time specific to that location, no the users location.

Each physical site has a timezone attribute string like "Europe/London" or "Europe/Amsterdam"

My datetimes are all stored and delivered from the DB in UTC.

Is there a clever simple way I can render my moment.js object in any specified timezone?

preguntado el 03 de mayo de 12 a las 21:05

No, pero podrías usar github.com/mde/timezone-js to convert. See also this issue (github.com/timrwood/moment/issues/162) on the moment.js github tracker; some tz format behavior has been deprecated to to varying Date.toString() implementations; it also points to timezone-js. -

I feared this might be the case and was somewhat in denial. moment.js is so elegant and small, it seems a travesty to pollute it with other libs. :-( -

4 Respuestas

Theoretically, you could do something like this.

moment.fn.formatInZone = function(format, offset) {
    return this.clone().utc().add('hours', offset).format(format);
}

moment().formatInZone('HH:mm:ss', 7);
moment().formatInZone('HH:mm:ss', -7);

However, this requires that you know the correct offset, so it won't take into consideration daylight saving time.

contestado el 04 de mayo de 12 a las 17:05

A lot of people talking about this issue get all verklempt about OMG you need to calculate the offset, but in a lot of cases you're sending date strings down from the server that already have the correct offset embedded in them (taking into account daylight savings time.) - Obie

If you want to display dates in ANOTHER timezone than the user is actually in, then you need to start looking into stuff like https://bitbucket.org/pellepim/jstimezonedetect (if you need to detect which timezone a user is in) and https://github.com/mde/timezone-js if you need to localize dates between zones.

jsTimezoneDetect which I linked to above will help you provide a shortlist of relevant timezones.

That you have your datetimes stored in UTC will make it pretty damn easy for you thanks to mde/timezone-js.

contestado el 04 de mayo de 12 a las 13:05

In node.js this is actually pretty simple using node-time (https://github.com/TooTallNate/node-time). Override the global Date object, then extend moment.js:

var time = require('time')(Date),
    moment = require('moment');

moment.fn.setTimezone = function(timezone, relative) {
    this.toDate().setTimezone(timezone, relative);
    return this;
}

moment.fn.getTimezone = function() {
    return this.toDate().getTimezone();
}

For good measure let's throw in a utility function to convert "incoming" date/time strings to UTC:

moment.fromTimezone = function(datetime, timezone) {
    return moment(datetime, "YYYY-MM-DD HH:mm").setTimezone(timezone, true).setTimezone("UTC");
}

Y puedes hacer esto:

var fmt = "YYYY-MM-DD HH:mm",
    datetime = "2013-03-21 00:40",
    timezone = "Israel",
    m = moment.fromTimezone(datetime, timezone);

console.log(datetime, "in", timezone, "is", m.format(fmt), "in UTC");
console.log(m.format(fmt), "in UTC is", m.setTimezone(timezone).format(fmt), "in", m.getTimezone());

Salida de Shell:

$ node mtz.js
2013-03-21 00:40 in Israel is 2013-03-20 22:40 in UTC
2013-03-20 22:40 in UTC is 2013-03-21 00:40 in Israel
$

respondido 21 mar '13, 01:03

About a year after this question was asked, Zona horaria del momento was introduced. Here's an example of how Moment Timezone can solve this problem.

const databaseDate = '2014-05-01T12:00:00Z';
const databaseTimezone = 'America/New_York';
const formatString = 'MMMM Do YYYY, h:mm:ss a';

const dateInUTC = moment.utc(databaseDate);
document.getElementById('dateInUTC').textContent = dateInUTC.format(formatString) + ' in UTC';


const dateInDbTZ = moment.utc(databaseDate).tz(databaseTimezone);
document.getElementById('dateInDbTZ').textContent = dateInDbTZ.format(formatString)  + ' in ' + databaseTimezone;

const dbDateWithoutTZ = '2014-05-01T12:00:00'; // no 'Z'
const dateInLocalTime = moment(dbDateWithoutTZ);
   document.getElementById('dateInLocalTime').textContent = dateInLocalTime.format(formatString) + ' in local time or ' + dateInLocalTime.utc().format(formatString) + ' in UTC';
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.17/moment-timezone-with-data.min.js"></script>
<dl>
<dt>UTC Date</dt>
<dd id="dateInUTC"></dd>
<dt>Timezone-formatted Date</dt>
<dd id="dateInDbTZ"></dd>
<dt>Bad: non-UTC date interpreted as "local time"</dt>
<dd id="dateInLocalTime"></dd>
</dl>

contestado el 23 de mayo de 18 a las 14:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.