MomentJS,如何忽略用户的本地时区并使用

MomentJS, how to ignore user's local timezone, and use

场景如下:

1- 用户打开网站,然后使用下拉字段输入 07:00,这将给我以下信息:

// 1578600000000 => 保存到数据库 // 2020 年 1 月 10 日星期五 07:00:00 GMT+1100(澳大利亚东部夏令时间)

用户本人在悉尼,这意味着他的本地时钟是GMT+1100

但是,他想将这个时间表示为 Asia/Tehran 时间,因为那是他明天要去的地方。所以本质上,他想让我完全忽略他的当地时间,把他看成是在Asia/Tehran。所以当他明天在 Tehran 时,他可以看到他的日历有 07:00am

另一方面,全世界的人都会看到他的空闲时间吗,比方说从 Australia/Perth

根据 momentJS 文档,我认为类似下面的方法有效,但事实并非如此。

首先,将时区转换为Asia/Tehran,也就是用户想要的地方:

const desiredTimeZone = 'Asia/Tehran';
let OriginalDesired = moment.tz(1578600000000,desiredTimeZone);

然后,在向 Australia/Perth 的人展示它时,确保它在他们的时区

const PerthTimeZone = 'Australia/Perth`; // this is dynamic, can be anything

OriginalDesired.clone().tz(PerthTimeZone);

我天真地认为这应该有效。但是我注意到原来的时间戳 1578600000000 是一个 UTC 时间戳,这意味着它不是真正的 07:00am,它实际上是 20:00pm,因为 Javascript
已从用户条目中减去 11 小时,这是原始用户的本地时区偏移量。

我设法通过以戏剧性的方式添加和减去偏移量来解决这个问题,但它只适用于一种情况。

const originalTime = 1578600000000;
const LocalAdjustment = moment(originalTime).tz("Australia/Sydney").utcOffset() * 60000;

const DesiredAdjustment = moment(originalTime).tz("Asia/Tehran").utcOffset() * 60000;
const newUTC = originalTime + LocalAdjustment - DesiredAdjustment;

并且在 Tehran

中向用户表示此内容时
  moment(newUTC).tz("Asia/Tehran").format('hh:mma'); // 07:00am.

我知道这可能很愚蠢,而且显然只适用于一种情况,但这是我要走的正确道路吗?或者有更简单的方法吗?

顺便说一句,所有的计算都在我的服务器上,也就是'UTC'。

你说:

1- User opens the website, and enters 07:00 am using a dropdown field, which will give me this : // 1578600000000 ...

你已经输了。如果本地时区不相关,则不要编写假定它是相关的代码。

换句话说,您可能有以下内容:

moment("2020-01-10 07:00")

相反,你应该有这样的东西:

moment.tz("2020-01-10 07:00", "Asia/Tehran")

或者更确切地说,您应该简单地将 "2020-01-10 07:00""Asia/Tehran" 发送到您的数据库,然后在您需要知道代表什么时刻时检索它们并将它们传递给 moment-timezone。

至于您的其他方法,从时间戳中添加或减去时区偏移通常不是一个好主意。 Unix 时间戳本质上是基于 UTC 的。添加或减去将产生不同的时刻,不调整时区。

考虑到您的代码返回的偏移量不正确的可能性很小(但并非不可能),因为在查找之前必须先移动它们。换句话说,德黑兰在相关日期处于 UTC+3:30,因此传递的时间戳必须在传递给 moment 构造函数之前 调整 3 小时 3 分钟。这导致循环逻辑,并且难以解决。它将显示接近转换的时间戳(无论是夏令时,还是特定时区标准时间的更改)。