1

我有一个日程安排应用程序,其中有一个我从头开始构建的日历。作为律师,您应该能够配置您的可用预订时间,如下所示:

澳大利亚律师的可用性:

1- 10/01/2020,从 07:00am 到 08:am ...

这就是我所做的:

1- 获取epochJavascript 中输入日期的编号:

  const dateFrom = new Date(firstOfJanSevenAm).getTime() // 1578600000000
// Fri Jan 10 2020 07:00:00 GMT+1100 (Australian Eastern Daylight Time)

  const dateTo = new Date(firstOfJanEightAm).getTime() // 1578603600000 
// Fri Jan 10 2020 08:00:00 GMT+1100 (Australian Eastern Daylight Time)

2-将其发送到NodeJS服务器并保存MongoDB

     Mongoose.save({
      from:dateFrom, //1578600000000
      from:dateTo    //1578603600000
     })

3-在日历中表示它:

    <div>{format(from, 'HH:mm')}</div>

一切都按预期工作。

现在,这位律师正在美国旅行,他在使用美国当地时间(任何城市)的咖啡店,他打开日历,他想添加一些可用性,但在悉尼时间。我需要为他提供时区下拉列表,以便他可以告诉我他希望新日期基于他的家Syndey

问题 :

1-我是否像我一样保存日期(作为数字),并将时区单独保存在它旁边,并且在表示它时,只需应用时区?

     Mongoose.save({
      from:dateFrom, //1578600000000
      from:dateFrom //1578603600000
      currentTimeZone : 'America/Costa_Rica',
      desiredTimeZone: 'Australia/Sydney'
     })

 <div>{formatWithTimeZone(from, 'HH:mm',desiredTimeZone)}</div>

这就是我所要做的吗?或者我是否天真地错过了一些会让我绊倒的东西?

回到我最初的问题,我在哪里做整个“始终将时间存储为 UTC”的事情?

我所意识到的是,当我使用我正在使用的库date-fns-tz并尝试将用户输入的日期转换为时UTC,我得到完全相同的输出:

      const dateFrom = new Date(firstOfJanSevenAm).getTime() // 1578600000000
      const dateFromUTC = zonedTimeToUtc(dateFrom,currentTimeZone) // 1578600000000
      // currentTimeZone is America/Costa_Rica, when he is in Costa Rica's caffee shop.
    enter code here

      1578600000000 === 1578600000000 = true 

那么为什么在将输入的日期转换为日期时会得到相同的输出UTC

4

2 回答 2

1

我将给你一个与技术实现脱钩的答案。让我们矛盾地思考一下,您有一个住在澳大利亚的律师和另一个住在瑞士的律师,如果您决定将时间存储在他们喜欢的位置会发生什么?

然后您需要保存两个信息:当然是时间(上午 11 点),但它是相对的,因此您还需要存储时区(澳大利亚上午 11 点)或(瑞士下午 1 点)

现在,如果您的律师前往法国会怎样?你想更新他所有的日历信息吗?上午 11 点不再是上午 11 点。

UTC 解决了这个问题,您只需要存储上午 11 点或下午 1 点。UTC 是任意绝对的,按照惯例是通用的。

因此,您的后端/数据库应始终以 UTC 存储此类信息。而且您需要一种方法来了解用户的时区,也许可以使用 Web 界面对其进行更新,并且可以将其存储在用户数据库中或仅存储在 cookie 中。也许您想通过使用用户的位置、IP、浏览器的语言等来自己推导出它。

现在您知道了他的时区,您的服务器可以向客户端发送 UTC(绝对)时间,客户端可以无缝显示正确(相对)时间。

客户端处理相对时间,服务器始终使其成为绝对时间。

于 2020-01-07T18:13:41.883 回答
1

那么为什么在将输入的日期转换为 utc 日期时会得到相同的输出?

返回的值是根据通用时间getTime从 1970 年 1 月 1 日 00:00:00 开始的毫秒数。

因此,UTC 和getTime两者都代表使用相同通用时区的时间点。

我是否像我正在做的那样保存日期,并将时区单独保存在它旁边,并且在表示它时,只需应用时区?

不要用日期保存时区。只需将日期保存为通用时间即可。如果您需要保存时区。这应该进入用户设置。但是,您可以猜测时区;因此,您无需保存此信息。

保存日期

当您将日期保存到数据库时,它应该由 UTC 时间字符串或 UNIX 时间戳表示,这两个选项都在下面演示。

UNIX 时间戳

UNIX 时间戳应该以秒为单位。getTime返回毫秒。您只需除以 1000 即可获得 UNIX 时间戳。

 const unixTimestamp = new Date('December 17, 1995 03:24:00').getTime() / 1000;

UTC 日期字符串

 const utcDate = new Date('December 17, 1995 03:24:00').toUTCString();

显示日期

当您从后端获取日期时,将其转换为正确的时区。

const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone

const fromUnix = utcToZonedTime(1578423483, timezone)
const fromUtc = utcToZonedTime('Fri, 02 Feb 1996 03:04:05 GMT', timezone)

结束的想法

处理时区可能会令人困惑。我不熟悉date-fns-tz。如果您可以选择,我建议您迁移到Moment.js。Moment.js 是当今事实上的标准 JavaScript 库——我强烈推荐它。

于 2020-01-07T18:26:09.260 回答