MySQL支持历史日期(如1200)吗?

use*_*291 18 mysql

我看不到任何关于这方面的信息.我在哪里可以找到Mysql可以支持的最早的日期?

Edu*_*ual 35

对于您在问题(1200年)中使用的具体示例,从技术上讲,事情会起作用.

但是,一般而言,这种用途的时间戳是不可取的.首先,范围限制是任意的:在MySQL中它是1000年1月1日.如果你正在使用12-13世纪的东西,事情就好了......但是如果在某个时刻你需要添加更旧的东西(10世纪或更早) ,日期将惨败,修复问题需要将所有历史日期重新格式化为更合适的日期.

时间戳通常表示为原始整数,具有给定的"滴答间隔"和"纪元点",因此该数字实际上是从纪元到所表示的日期所经过的刻度数(或者反之为负数日期).这意味着,与任何固定的整数数据类型一样,可表示值的集合是有限的.大多数时间戳格式我知道牺牲范围有利于精度,主要是因为需要执行时间算术的应用程序通常需要具有相当高的精度; 而需要使用历史日期的应用程序很少需要执行严格的算术运算.

换句话说,时间戳用于精确表示日期.对于历史日期来说,第二次(或甚至是一小部分的)精确度是没有意义的:你能告诉我,直到毫秒,亨利八世何时加冕为英格兰国王?

在MySQL的情况下,格式本质上被定义为"4位数年",因此任何相关的优化都可以依赖于年份将具有4位数的假设,或者整个字符串将具有恰好10个字符("yyyy-" mm-dd")等等.运气问题,你在标题上提到的日期仍然适合,但即使依赖它仍然很危险:除了数据库本身可以存储的内容之外,你需要知道什么是你的服务器堆栈的其余部分可以操纵.例如,如果您使用PHP与数据库进行交互,那么尝试处理历史日期很可能会在某些时候崩溃(在32位环境中,UNIX样式时间戳的范围是1901年12月13日到2038年1月19日).

总结:MySQL将正确存储任何具有4位数年份的日期; 但通常使用历史日期的时间戳几乎可以保证引发问题和头痛.我强烈建议不要这样使用.

希望这可以帮助.


编辑/添加:

谢谢你这个非常有趣的答案.我应该为历史日期创建自己的算法还是选择另一个数据库但是哪一个? - user284523

我不认为任何数据库对这种日期有太多的支持:使用它的应用程序通常具有足够的字符串/文本表示.实际上,对于第1年及以后的日期,文本表示甚至会产生正确的排序/比较(只要日期由数量级表示:y,m,d顺序).然而,如果还涉及"否定"日期,那么比较将会中断(它们仍将比任何正日期更早进行比较,但比较两个负数日期将产生相反的结果).

如果您只需要第1年及以后的日期,或者如果您不需要排序,那么您可以通过使用字符串使您的生活更轻松.

否则,最好的方法是使用某种数字,并定义自己的"tick interval"和"epoch point".一个好的间隔可能是几天(除非你真的需要进一步的预测,但即使这样你也可以依靠"真实"(浮点)数而不是整数); 一个合理的时代可能是1月1日.主要问题是将这些值转换为文本表示,反之亦然.您需要记住以下细节:

  • 闰年还有一天.
  • 闰年的规则是直到1582年的"4的任意倍数",当时它从朱利安变为格里高利历,变成"4的倍数,除了那些是100的倍数,除非它们也是400的倍数".
  • 朱利安历法的最后一天是1582年10月4日.第二天,格里高利历的第一天,即1582年10月15日.跳过10天,使新的日历与季节再次匹配.
  • 正如评论中所述,上述两条规则因国家而异:教皇国和一些天主教国家确实在规定的日期采用了新的日历,但许多其他国家需要更长的时间(最后一个是1926年的土耳其).这意味着1582年罗马教皇公牛与1926年最后一次采用之间的任何日期都将是模糊的,没有地理背景,甚至更加复杂.
  • 没有"第0年":第1年的前一年是第-1年,或公元前1年.

所有这些都需要非常复杂的解析器和格式化器功能,但是除了许多逐个案例的突破之外,并没有太多的复杂性(编码很繁琐,但非常简单).使用数字作为底层表示可确保对任何值对进行正确的排序/比较.

了解这一点,现在您可以选择更适合您需求的方法.

  • 我希望SO允许少量的+2支持以获得非常好的答案.不仅要感谢非常有用的细节,还要使它成为一个有趣的读物.我有一个小狡辩,我认为一般来说"BCE"比"BC"更受欢迎. (2认同)

Phi*_*oss 12

文档:

日期

一个约会.支持的范围是"1000-01-01"到"9999-12-31".

  • 刚发生在我身上 - 如果支持的日期范围达到9999年,那么简单的时移应该可以解决问题.虽然重要的是按年数除以4来排列闰年. (2认同)

Pab*_*ruz 6

是.MySQL日期从1000年开始.