【问题标题】:How to get difference between dates in different timezones using moment?如何使用时刻获取不同时区的日期之间的差异?
【发布时间】:2019-11-15 02:05:44
【问题描述】:

我正在使用 momentJS 来获取 2 个日期之间的差异。这是我的代码:

const createdAt = "2019-11-15 09:45:21"; // Sample data from mysql database

// Add time since created
const created = moment(createdAt);
const now = moment();
// get the difference between the moments
const diff = now.diff(created);
//express as a duration
const diffDuration = moment.duration(diff);
const days = diffDuration.days().toString().padStart(2, 0);
const hours = diffDuration.hours().toString().padStart(2, 0);
const minutes = diffDuration.minutes().toString().padStart(2, 0);

使用该代码,我可以正确获取天、小时和分钟的差异。安装mysql的服务器在菲律宾,createdAt的值是mysql自动生成的。

现在,当我尝试更改我电脑的时区时,我得到了错误的日期差异。我得到负值。

我尝试过添加utc():

const created = moment.utc(createdAt);
const now = moment.utc();

我仍然没有得到任何正确的值。我错过了什么吗?是否有可能做到这一点?提前致谢。

【问题讨论】:

  • 所以数据库中的时间字符串是菲律宾时间?在这种情况下,您需要创建一个反映适当时区的 momentjs 对象:jsfiddle.net/khrismuc/k5zj4ha0
  • @ChrisG 我不明白这一点。是否可以使其动态化?比如你不知道服务器在哪里运行?
  • 如果服务器不存储时区,那将如何工作?要确定确切的时间点,您需要知道哪个时区是 9:45。唯一的选择是更改后端,以便所有时间戳都使用 UTC。
  • Chris 的建议是更好的选择。您的后端时间戳应基于 UTC。然后你就不需要将它们解析为当地时间。一般来说,应该这样编码,使得服务器的时区设置永远不会影响应用程序的行为。
  • 另外,关于 MySQL 方面的内容,您并没有说太多。你读过DATETIME and TIMESTAMP types in MySQL 之间的区别吗?您的 createdAt 字段是哪种类型?你如何找回它?到这段代码的其余部分开始时,它真的是一个字符串吗?或者你只是代表一些其他对象(也许是一个 JS Date 对象?)

标签: javascript timezone momentjs


【解决方案1】:

上面的createdAt 时间不是 UTC 格式,因此您需要通过添加/减去本地时间或 UTC 时间的小时数来更新值。最好将相关日期转换为 UTC,然后从那里执行您的diff

看看下面的解析和值选项:

// utc time now
const utcTime = moment.utc();
console.log(utcTime.toString());

// time recorded at server
const philliTime = moment('2019-11-15 09:45:21', 'YYYY-MM-DD HH:mm:ss');
console.log(philliTime.toString());

// need to add 8 hours as philli is +8 hours
philliTime.add(8, 'h');
console.log(philliTime.toString());

// options using parseZone
const optionBPhilli = moment.parseZone('2019-11-15 09:45:21 +08:00', 'YYYY-MM-DD HH:mm:ss ZZ');
console.log(optionBPhilli.toString());

const optionBUTC = moment.parseZone('2019-11-15 09:45:21 +00:00', 'YYYY-MM-DD HH:mm:ss ZZ');
console.log(optionBUTC.toString());

console.log(optionBPhilli.diff(optionBUTC, 'h'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

有关解析字符串的更多信息,请查看moment docs 并查看UTC parsing.

【讨论】:

  • 永远不要添加来调整时区。这创造了一个不同的时刻。 parseZone 方法更好,但要仔细观察这些格式化标记的大小写。 h 采用 12 小时制。 H 采用 24 小时制。在这种情况下,HH 更合适(给定前导零)。
  • (另外,UTC 不是“格式”。我认为您的意思只是输入字符串不包含任何时区或偏移信息。)
  • 感谢@MattJohnson-Pint - 根据您的建议并在再次检查文档后更新了格式。
猜你喜欢
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多