在数据库中存储完整日期或仅一年

时间:2014-09-09 12:58:49

标签: php mysql date

我正在开发一个项目,其中有大量日期需要存储在数据库(MySQL)中。

问题是,有些日期已满,但有些日期只有一年。

例如,日期是这样的:

  • 1980年1月20日
  • 2011
  • 2012年2月25日
  • 2008

我在PHP中使用函数date()strtotime()函数来转换Y-m-d格式的日期。完整日期已成功转换,但只有一年的日期将转换为今天的错误日期。

问题是:

  • 如何成功确定哪个是完整日期,哪个只是PHP中的一年,然后仅将date()strtotime()函数应用于完整日期?
  • 如何在数据库中保存这些变体(完整日期和仅年份)? (如果可以在一个列中)
  • 从数据库中提取时,如何知道日期是满还是只有一年,并相应地显示它?

修改

混淆。我将在日期进行操作,例如按日期排序,包括完整日期和仅年份日期。是否:

  • 存储年份为1990-00-00并在检索时检查零?
  • 存储年份为1990-01-01,另一个布尔字段是年份?
  • 将年,月,日作为整数存储在不同的列中?

6 个答案:

答案 0 :(得分:1)

在数据库中存储您正在处理的对象。您可以存储像John Smith这样的名字。就像它是或你分别存储名字和姓氏(但在哪里放中间名?:-)这取决于你的要求。对于一个系统,必须按姓氏过滤和排序,因此姓氏必须是单独的列。另一个系统可能只对全名感兴趣,而不用担心在" Wu Chang"是第一个,也是最后一个名字。

同样在这里。通常将日期存储为DATE或DATETIME列。但是你对那些日期和月份可能未知的年份感兴趣。所以你分开存放这些。这一年可能有NOT NULL约束,而日和月可以为空。

我建议年月和日的单独整数列。不要使用一种必须知道的格式的字符串,这种格式可能会不时被破坏。

编辑:我只是注意到我还没有回答你的PHP问题:好吧,当你得到一个由四位数组成的字符串时,它就是一年,否则你可以将它转换为日期,然后它&# 39;日期,或者你可以,然后它是无效的数据。

答案 1 :(得分:0)

确保在日期的未知部分使用零。所以插入'2014-00-00'而不仅仅是2014。

答案 2 :(得分:0)

您可以查看它是否为数字。如果是真的那么这是一年。因此在将其转换为日期之前添加“01/01 /”。它将被视为1月份的事件。你需要一个单独的字段isYear(一个布尔值)来确定它是一年还是一个日期。

答案 3 :(得分:0)

要将不同的日期格式保存在db中的同一列中,您必须将它们另存为String。如果您想对它们执行某些操作,这没有意义,但如果您只想显示该值则可以。话虽这么说,如果你想对它们执行一些操作,我建议在db中有2列,一个用于TIMESTAMP类型的全年,而一年用1作为YEAR类型。这样,您还可以通过检查哪个列不为空来知道要加载哪种类型,从而解决您的其他问题。

要回答您的第一个问题,您可以通过检查字符串长度来检查哪个是完整日期,哪个只是年份。如果修剪后的字符串超过4个字符,那么它必须是完整日期。如果您发送了一些格式不正确的数据,我仍然会进行错误处理。

阅读其他回复,例如,我不会将其设置为01/01/2014,因为如果您的实际日期是01/01/2014,则无法确定它是作为完整日期还是仅作为年份发送。或者,您可以按照此方法添加一个BIT类型的列来表示一个布尔值,表明它是否为fullYear

答案 4 :(得分:0)

您可以检查给定字符串是否仅通过将其传递给date_create_from_format来指定年份:

$s = '2014';
if (date_create_from_format('Y', $s))
    $t = strtotime($s.'-01-01');
else
    $t = strtotime($s);

echo date('Y-m-d H:i:s', $t);

答案 5 :(得分:0)

如果完整日期的格式是一致的,那么您可以通过检查字符串中的空格来检查是否有完整的日期。

其次,如果您的表格中有日期列,则可以只保存年份值,并将月份和日期保留为零。

if (strstr(trim($date), ' ') !== false) {
    // space was found, this is a full date
    $mysqlDate = /* ... strtotime, etc. */
} else {
    // space was not found, this is just a year date
    $mysqlDate = trim($date) . '-00-00';
}

在选择时,您可以通过检查日期值中的零来过滤仅年份日期。

不是一个漂亮的解决方案,但如果您打算将它们全部存储在同一列中,那么它就会突然出现。