如何在不使用日期字段的情况下选择两个日期之间的所有记录?

时间:2011-01-05 13:36:27

标签: mysql sql date time

我有一个MySQL数据库,我需要能够在1970年之前存储日期,所以我需要一种自定义方式来存储日期。就我而言,我需要能够存储截至目前的日期,并且可以追溯到历史。显然,历史上早期的事件需要较少的准确性 - 几天,几个月,甚至几年变得不那么重要,因为我们没有这些历史信息。涉及日期的主要查询将是选择两个给定日期之间的记录。

我原以为使用这种格式:

Year - int(6) | Month - tinyint(2) | day - tinyint (2) | time - time | AD tinyint (1) | mya - int (11)
但是,当涉及到实际使用这种格式的数据时,它变得困难。例如,如果我想获得两个日期之间的所有记录,那就像(伪代码而不是SQL):

get all where year between minYear and maxYear
if year == minYear, month >= minMonth
if year == maxYear, month <= maxMonth
if month == minMonth, day >= minDay
if month == maxMonth, day <= maxDay
if day == minDay, time >= minTime
if day == maxDay, time <= maxTime

或其他什么,这似乎是一种正确的痛苦。我可以在0 AD之前/之后存储几秒钟,但这会占用太多数据! 2011年=自公元0年以来的64亿秒。有没有人对这个问题有任何想法?

3 个答案:

答案 0 :(得分:2)

我会存储自某一天起的天数。可以使用各种日期作为零日。这些通常称为儒略日,见wikipaedia

当您存储0 AD的日期时,我会查看按时间顺序排列的朱利安日(CJD),以便您的所有值都是正值。

作为副作用,这意味着您只需要查看处理不同的日历(例如,当他们更改为格里高利时以及年初时更改或使用伊斯兰日历时)当您转换为或更早了解更多日历时关于实际日期的详细信息,

如果对日期感兴趣不要打扰秒,因为这些事情使事情变得复杂,也意味着你必须处理更大的数据(比长时间更长)和时间zomes等....

答案 1 :(得分:1)

这取决于您想要运行的查询类型。

您可以将日期存储为字符串YYYYMMDDHHMMSS,该字符串将按时间顺序排序并允许您查找范围内的日期。另见ISO 8601 http://en.wikipedia.org/wiki/ISO_8601

答案 2 :(得分:1)

您需要至少一个日期来创建间隔。我为start_date使用了一个日期字段,并且可以是一个间隔,可以是一个秒数,也可以是一个固定的间隔,如ENUM(日,月,年)。这取决于您正在使用的数据。

对于DATE,支持的范围是“1000-01-01 00:00:00”到“9999-12-31 23:59:59”,但这意味着虽然早期的值可能有用,但是不保证。我看到你可以毫无问题地使用0001-01-01。

FOR BC值。 我不知道是否有标准,但我已经看到系统说明了自己的起点。假设您的数据将在AD之前,但不会超过公元前1000年。您可以将您的0年表示为-2000,您对所有日期应用(年 - 2000)差异,甚至可以构建仅适用于您的项目的包装日期类。您可以将时间指定为整数,并且可以毫无问题地执行所有操作,特别是如果您不使用数天或数月的粒度。目前的日历在过去是不可靠的,因为几个世纪以来错误地计算了日期的准确性,并且由一些可以进行计算的修补程序进行修复非常困难。

// lets save the 1st of January 214 BC
214-2000 = -1786
save the data as 01-01-1786
// you will probably want to save it actually as 01-01-1785 
// to compensate for the loss of the year 0

我建议你保留日期格式,因为它可以让你直接在mySql中进行快速DATE操作。

更新以计算班级中的leap years

if year modulo 400 is 0
   then is_leap_year
else if year modulo 100 is 0
   then not_leap_year
else if year modulo 4 is 0
   then is_leap_year
else
   not_leap_year