Datetime 在不同的RDBMS中一致地处理日期时间

Datetime 在不同的RDBMS中一致地处理日期时间,datetime,timezone,rdbms,Datetime,Timezone,Rdbms,我正在计划一个分布式应用系统,它将与不同类型的RDBMS进行通信。其中一个要求是跨所有RDBMS类型一致地处理日期时间。所有日期时间值必须为毫秒精度,包括时区信息,并存储在单个列中 由于不同的RDBMS处理日期和时间的方式不同,我担心在这种情况下不能依赖于它们的本机列类型,因此我必须提出不同的解决方案。(如果我错了,欢迎你给我指路。) 无论是什么解决方案,理想情况下都应该允许在SQL级别轻松排序和比较。其他方面,如可读性和使用SQL datetime函数的能力并不重要,因为这一切都将由网关服务处

我正在计划一个分布式应用系统,它将与不同类型的RDBMS进行通信。其中一个要求是跨所有RDBMS类型一致地处理日期时间。所有日期时间值必须为毫秒精度,包括时区信息,并存储在单个列中

由于不同的RDBMS处理日期和时间的方式不同,我担心在这种情况下不能依赖于它们的本机列类型,因此我必须提出不同的解决方案。(如果我错了,欢迎你给我指路。)

无论是什么解决方案,理想情况下都应该允许在SQL级别轻松排序和比较。其他方面,如可读性和使用SQL datetime函数的能力并不重要,因为这一切都将由网关服务处理

我想把我的DateTime值存储在一个无符号的largeint列类型(8字节)中。我还不确定所有的RDBMS(MSSQL、Oracle、DB2、PostgreSQL、MySQL,可能还有其他一些)是否真的有这样一种类型,但现在我假设它们有

至于存储格式。。。例如,2009-01-01T12:00:00.999+01:00的存储方式类似于?20090101120000999??,它的大小不超过8个字节

我可以用这种方式存储的最短日期时间是0001-01-01T00:00:00.000+xx:xx,最长是8000-12-31T23:59:59.999+xx:xx,这给了我足够的时间跨度

由于最大无符号largeint值为18446744073709551615,因此我将使用以下3位数字(用A和BB标记)来存储时区信息:axxxxxxxxxxxxxxbb

考虑到0001..8000的最大年跨度,A可以是0或1,BB可以是00到99之间的任意值

现在的问题是:

  • 你觉得我提出的解决方案怎么样?它是有价值的还是愚蠢的

  • 如果没有更好的方法,您建议如何将剩余的三位数字最好地用于时区信息


我建议您自1970年以来以毫秒为单位存储日期时间信息(Java风格)。 这是存储日期时间信息的标准方法,此外,它在空间方面比您的建议更有效。因为在您的建议中,有些数字是“浪费”的,即月份数字只能存储00-12(而不是00-99),以此类推。 您没有指定什么是您的开发语言,但我相信您可以找到许多将日期转换为毫秒的代码段。 如果你是在.NET中开发的,他们对滴答声有着类似的概念。(您也可以使用此信息)

关于时区,我将添加另一列来仅存储时区指示

请记住,您选择的任何格式都应保持两个日期之间的一致性,即,如果D1>D2,则格式(D1)>格式(D2),这样您就可以查询数据库自某个日期以来的更改,或者查询两个日期之间的更改

其中一个要求是跨所有RDBMS类型一致地处理日期时间

请注意,不同数据库系统的日期-时间处理能力差异很大。范围从几乎不支持(SQLite)到优秀(Postgres)。有些数据类型(如Oracle)可能会混淆情况,因此请仔细研究,不要做出假设

您不应该建立一个笼统地说我们必须支持“任何或所有数据库”的需求,而应该更加具体。准确研究哪些数据库实际上可能是在现实世界中部署的候选数据库。“任何或所有数据库”的要求都是幼稚和不现实的,因为数据库在许多功能上都有所不同-日期-时间处理只是多数据库支持问题的开始

SQL标准几乎没有涉及日期时间的主题,大致定义了几种类型,很少讨论日期时间工作的细微差别和复杂性

还要注意,大多数编程平台对日期时间处理的支持非常差。请注意,Java凭借其设计精良的Java.time类在该领域处于业界领先地位。该框架是从Java项目演变而来的,该项目作为一个组件移植到.Net平台

所有日期时间值必须为毫秒精度

很好,你指定了那个重要的细节。了解各种系统将日期时间值解析为整秒、毫秒、微秒、纳秒或其他值

包括时区信息并将其存储在一列中

精确定义时区

了解UTC和时区的偏移量之间的区别:第一个是小时分秒加上或减去的数值,第二个是格式为
的大陆/地区
,是特定地区人民使用的偏移量过去、现在和未来变化的历史

CST、PST、IST等2-4个字母的缩写不是正式的时区名称,没有标准化,甚至不是唯一的(避免使用)

由于不同的RDBMS处理日期和时间的方式不同,我担心在这种情况下不能依赖于它们的本机列类型,因此我必须提出不同的解决方案

SQL标准确实定义了一些主要数据库支持的几种类型

  • 带有时区的时间戳
    表示一个时刻,即时间线上的一个特定点。我隐约记得听说一个数据库实际上存储了传入的时区。但大多数情况下,如Postgres,使用传入值上指示的时区调整为UTC,然后存储该UTC值,最后丢弃区域信息。检索时,将返回UTC值。小心那些具有防混淆功能的工具和中间件,它们在检索之后和向用户显示之前应用默认时区
  • 不带时区的时间戳
    rep