Node.js 寻找与时区和日期相关的模式前端(React)和后端(nodejs)

Node.js 寻找与时区和日期相关的模式前端(React)和后端(nodejs),node.js,reactjs,timezone,timezone-offset,timestamp-with-timezone,Node.js,Reactjs,Timezone,Timezone Offset,Timestamp With Timezone,我正在寻找开发模式,为一个国家的不同用户或仅仅是不同的国家处理不同的时区 我想知道,在现有的世界级软件中,是否有一些被广泛接受和实现的软件 到目前为止,我的想法是存储具有特定时区的用户配置文件,并更改后端查询中的所有日期 后端将接收本地时间的日期,包括TZ,后端将在数据库中以UTC格式存储它 对于检索结果列表来说,这非常有效,但是对于需要分组的查询(例如,10月份的所有销售),如果您处于负TZ,则还应分组9月30日的日期;如果您处于正时区,则分组11月1日的销售日期 对于这种情况,直接使用存储的

我正在寻找开发模式,为一个国家的不同用户或仅仅是不同的国家处理不同的时区

我想知道,在现有的世界级软件中,是否有一些被广泛接受和实现的软件

到目前为止,我的想法是存储具有特定时区的用户配置文件,并更改后端查询中的所有日期

后端将接收本地时间的日期,包括TZ,后端将在数据库中以UTC格式存储它

对于检索结果列表来说,这非常有效,但是对于需要分组的查询(例如,10月份的所有销售),如果您处于负TZ,则还应分组9月30日的日期;如果您处于正时区,则分组11月1日的销售日期

对于这种情况,直接使用存储的用户TZ,并使用select子句中的一些db函数将其减去/添加到从db检索的日期时间中

我能解释一下吗


记住,例如,如果我必须检索一些销售数据,例如db,从9月1日开始的销售数据,只是为了重述您告诉我们的内容:

  • 您会收到类似于
    2020-11-16T12:34:56-08:00
  • 您可以按照UTC(
    2020-11-16T20:34:56Z
    )将其存储到MySQL中的
    datetime
    字段中
  • 您还拥有用户的时区,作为IANA时区标识符(
    America/Los_Angeles
  • 现在,您需要编写一个查询来获取一段时间内的所有数据,例如给定月份内的所有数据
在MySQL中,
datetime
类型在处理时区转换的方式上与
timestamp
类型不同。发件人:

MySQL将时间戳值从当前时区转换为UTC进行存储,并从UTC转换回当前时区进行检索。(其他类型(如DATETIME)不会出现这种情况。)

因此,如果要使用
时间戳
类型,那么在运行查询时,您唯一需要做的就是将会话时区设置为用户的时区。(阅读每个会话的时区。)

您提到,出于性能考虑,您选择datetime而不是timestamp。这不是一个普遍的真理。我会仔细查看您的实际使用情况,看看您是否存在性能问题。更可能的情况是您缺少索引或编写了不可搜索的查询。据我所知,
timestamp
类型没有广泛的性能问题

如果您仍然想使用
datetime
类型,那么MySQL不会为您进行时区转换。因此,您需要首先将开始/结束日期时间从其本地时间转换为UTC。然后可以对这些UTC值执行范围查询

无论采用哪种方法,您都需要考虑哪个时区与查询实际相关。在许多情况下,重要的是特定于业务的时区。在其他情况下,它将是用户。您给出的关于“10月份所有销售”的用例很好地说明了这一点。如果客户处于不同的时区,那么对于业务而言,这可能确实与客户不同。您可能希望他们有所不同,或者您可能希望迫使客户从企业的角度看待事物,反之亦然。这实际上只取决于你如何经营这项业务

最后—此类查询应始终作为范围查询执行,即从开始到结束。通常这最好用
where
子句表示为半开区间,例如:

从OrderDate>=@开始和<@结束的订单中选择*
但是,如果要聚合结果,并且需要使用
group by
子句,则需要执行一些额外的步骤:

  • 如果业务只有一个时区,则可能需要添加第二个字段,其中包含预转换为该时区的数据。它应该是
    日期
    日期时间
    ——而不是
    时间戳
    。然后可以将该字段用于分组

  • 如前所述,您可能需要将子查询作为范围查询运行,但在分组之前,先将其转换为特定时区。您可以使用MySQL
    convert\utz
    函数来实现这一点


您的后端是否只接收日期值(如
2020-11-16
)或日期时间值(如
2020-11-16 12:34:56
)?此外,您是否已阅读并理解用户时区需要是时区标识符(如
美国/纽约
),而不是时区偏移量(如
-05:00
)?您正在运行哪个数据库平台,存储数据的字段是什么数据类型?感谢@MattJohnson Pint的回复,我的问题不在于过滤,我正在正确地为后端提供相应时区的时间戳。我的问题是,只有当我必须按月份分组时,才可以很好地进行周期筛选,但是显示8月份的销售额(例如UTC)应该在9月份分组。谢谢你的维基链接,如果你想要一个真实的答案,我仍然需要你回答我的问题。我使用的是Mysql和字段数据类型datetime,因为我读过timestamp有严重的性能问题。是的,我理解区域标识符你错过了第一个问题。你是在处理日期还是日期+时间?换句话说,是“本订单于2020年11月16日下订单”中的订单日期,还是“本订单于2020年11月16日12:34:56在
美国/洛杉矶
”中的订单准确本地时间+日期+时区,还是您收到日期+时间+偏移量,如
2020-11-16T12:34:56-08:00
?这很重要。