在数据库中保存日期有比time()更好的方法吗?

3

我习惯于将日期保存为INT(11),并使用time()函数。考虑到time()的限制,是否有更好的方法来保存日期?

我不想使用数据库自带的DATE类型(以及所有数据库自带的日期函数)。

谢谢。


6
数据库提供的日期类型是更好的选择。为什么你不想使用它呢?既然数据库已经提供了正确的选项,为什么还要追求第三种选择呢? - user229044
3
为什么不使用内置的DATE和DATETIME列类型? - Sander Marechal
1
因为我习惯使用我的编程语言(在这种情况下是 PHP)来管理日期。 - anon
1
@yes123我完全理解你的担忧。我很久以前就停止使用DATE和DATETIME了,因为解决兼容性问题需要太多的痛苦。话虽如此,如果“time()”是限制,那么数据库也不会做得更好。 - Christian
2
使用DATE类型会更好,因为它具有许多有用的函数。INT(11)是次佳选择,因为INT处理速度快。您想要避免time()的哪些时间限制?DATE有什么问题吗? - Phil Lello
显示剩余11条评论
5个回答

5

好的,从评论中我理解到,使用time()的问题在于我们要表示01 / 01 / 1970到2038年之外的日期。

在这种情况下,我认为最好将日期格式化为YmdHis,存储在BIGINT中(如果不需要时间,则只需Ymd)。您可以使用date_create(“now”) ->format($fmt)而不是time(),其中$fmt分别为仅日期的'Ymd'或日期+时间的“YmdHis”

这给出了一个具有时间的最新日期,介于922,337,203AD和早于-922,337,203BC之间,或者没有时间的INT中为214,748AD至-214,748BC。


1
终于有人说了些有用的东西。 - dynamic
啊,不,fmt只是一个占位符,可以是'YmdHis'或'Ymd' :O - Phil Lello
@jason:这不是和将time()存储在数据库中几乎相似吗?我认为数百万的网站都这样做,没有任何问题。 - dynamic
@yes123,看起来这种观点可能不准确,因为此页面上排名最高的回答都鼓励您使用本地方式。但是没错,数百万其他网站也这样做。 - Jason McCreary
当然,如果这成为一个问题,代码/数据库可以更新(只要日期代码在几个函数中而不是内联,就很容易)。 - Phil Lello
显示剩余8条评论

1

使用 $_SERVER['REQUEST_TIME']

它是整个请求的常量,比 time()(和 UNIX_TIMESTAMP())更快,因为它只需要进行数组查找而不是函数调用。


1
我完全不担心time()的缓慢。 - dynamic
如果性能不是问题,那么你应该使用DATE/DATETIME。你可以切换到完全自定义的时间系统,例如朱利安日期(从公元前4713年开始),但我发现这很麻烦。 - Halcyon
1
那个不相关。$_SERVER['REQUEST_TIME'] 更快,这就是我想说的。 - Halcyon
对于直接在PHP中使用:是的,200%。对于SQL,在理论上是可以的,但是谁说MySQL在调用“UNIX_TIMESTAMP()”时不使用类似的更快方法呢?另一个问题是如果PHP和MySQL没有设置为相同的时区,则稍后的DATE / TIME计算将是错误的。 - Capsule
如果你想的话,可以测试一下,但这可能不太可能发生。幸运的是,Unix时间戳不受时区影响,因为它是在格林威治标准时间(我想)下定义的。 - Halcyon

0

日期时间更易于调试和阅读,但与时间戳相同的努力用于日期格式化。查询中的NOW关键字使事情变得干净整洁,特别是如果您不需要除查询之外的变量:

INSERT INTO `mytable` (`id`,`title`,`created`) VALUES (NULL, 'my awesome record', NOW());

格式化DATETIME比较困难,因为你最终需要将其转换为时间戳,然后再转换回所需的任何格式。 - Christian
如果您在查询中执行此操作,则并不真正困难:select UNIX_TIMESTAMP(NOW()); - Adam Purdie
1
是的,但你不能用时间戳表示1970年1月1日之前的日期,所以要么很难要么不可能,你自己决定吧 ;) - Halcyon
抱歉,我在帖子中漏掉了 (以及所有 db own date 函数) 的部分。 - Adam Purdie
@Frits - 那只是个神话 ;). 我过去曾经成功地保存到1600,而且效果非常好(我指的是一个具体的案例)。 - Christian
为了澄清我之前的评论,平台构建定义了整数的大小,这进而定义了您可以覆盖的日期范围。此外,负时间戳可与早于1700年的日期很好地配合使用(继续尝试 date('Y',-200000000) => 1963)。 - Christian

0

它不是“灵活”的,而是明显“限制性”的,这样做可能更容易出错,也不直观。至于效率,我真希望他们所做的混乱至少是高效的... - Christian
“我说‘我不想使用数据库[]’的哪一部分你没有听懂?” - dynamic
从来没有遇到过任何问题,如果你曾经学过60进制的微积分:http://en.wikipedia.org/wiki/Babylonian_mathematics。这就是为什么你会感到困难,因为你熟悉的是10进制的微积分,而秒-分钟-小时-月份-年份都是基于60的 :) 祝你在巴比伦好运! - Igor
@yes123 如果我们不了解你为什么要避免使用INT和DATE,我们怎么知道你喜欢什么呢? - Phil Lello
@phil 我可以使用INT,这不是问题。我相信问题只是在于time()函数只支持到2038年。 - dynamic

0

你可以使用内置的数据库类型来处理日期和时间,或者在表中创建三个整数列,并将日期保存为整数。无论哪种方法都可以,只要易于处理即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接