此处先前的答案将我指向用于 javascript 日期处理的moment.js,我真的很高兴找到它。我可以很高兴地解析和操作。
我网站上的用户查看与不同物理站点/位置相关的信息,我想在特定于该位置的时间显示相关的日期时间,而不是用户位置。
每个物理站点都有一个时区属性字符串,例如“Europe/London”或“Europe/Amsterdam”
我的日期时间都以 UTC 格式从数据库存储和传递。
有没有一种聪明简单的方法可以在任何指定的时区呈现我的 moment.js 对象?
此处先前的答案将我指向用于 javascript 日期处理的moment.js,我真的很高兴找到它。我可以很高兴地解析和操作。
我网站上的用户查看与不同物理站点/位置相关的信息,我想在特定于该位置的时间显示相关的日期时间,而不是用户位置。
每个物理站点都有一个时区属性字符串,例如“Europe/London”或“Europe/Amsterdam”
我的日期时间都以 UTC 格式从数据库存储和传递。
有没有一种聪明简单的方法可以在任何指定的时区呈现我的 moment.js 对象?
理论上,你可以做这样的事情。
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);
但是,这要求您知道正确的偏移量,因此它不会考虑夏令时。
如果您想在用户实际所在的另一个时区显示日期,那么您需要开始查看https://bitbucket.org/pellepim/jstimezonedetect之类的内容(如果您需要检测用户所在的时区)和https://github.com/mde/timezone-js如果您需要在区域之间本地化日期。
我在上面链接的 jsTimezoneDetect 将帮助您提供相关时区的候选名单。
多亏了 mde/timezone-js,您将日期时间存储在 UTC 中会让您非常轻松。
在 node.js 中,使用节点时间( https://github.com/TooTallNate/node-time )实际上非常简单。覆盖全局 Date 对象,然后扩展 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();
}
为了更好地衡量,让我们引入一个实用函数来将“传入”日期/时间字符串转换为 UTC:
moment.fromTimezone = function(datetime, timezone) {
return moment(datetime, "YYYY-MM-DD HH:mm").setTimezone(timezone, true).setTimezone("UTC");
}
你可以这样做:
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());
外壳输出:
$ 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
$
在提出这个问题大约一年后,引入了Moment Timezone。这是 Moment Timezone 如何解决此问题的示例。
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>