存储PHP DateInterval的MySQL数据类型是什么?

6
我希望在MySQL数据库中存储一个PHP DateInterval。为此,最好使用哪种数据库数据类型以便对DateInterval进行序列化?(即我想将其存储,然后稍后从数据库值创建一个DateInterval)。

1
不确定你为什么需要它,但如果你想的话,可以使用varchar。 - Just_Do_It
1
你想存储 PHP 日期间隔格式,以便稍后创建日期间隔吗?这可能很有趣。https://www.w3schools.com/PHP/func_date_interval_format.asp。将其存储为字符串? - Ryan Vincent
1
@Don'tPanic,我想过这个问题,但我不想限制它只能为“天”,以防将来用户需要说“1天,24分钟,39秒”。此外,我试图使应用层尽可能轻松地将此间隔加减到DateTime上。 - Josh Petitt
1
@RyanVincent,是的,请存储一个DateInterval,以便稍后可以使用它来创建一个DateInterval。 - Josh Petitt
4
当然有不同的方法可以实现,但我会选择使用varchar,并存储构造函数所采用的间隔规范,如“P35D”,“P1DT24M39S”等。 - Don't Panic
显示剩余4条评论
2个回答

3

您可以在DateInterval的构造函数中使用以下格式进行序列化:$interval->format("P%yY%mM%dDT%hH%iM%sS");

但是需要注意的是,您无法通过构造函数还原invert(符号)或者days(天数)的数量,这两个属性是通过DateTime->diff(DateTime)直接初始化的。如果您不需要这些信息,使用format即可。但如果您需要它们,最好选择使用serialize($interval)


这里提到的观点很好!format确实是更加整洁的方法。而且我之前还没有考虑过反向操作。如果负间隔是一个问题,那么在创建对象后将反向操作单独存储在一个bool列中,并在设置完毕后进行设置比存储序列化对象要更好些。 - Don't Panic

3
我建议存储DateInterval构造函数所需的间隔规范,例如“P35D”,“P1DT24M39S”等。
我之所以这样选择的原因是:
1.它很简单。如果您让用户选择特定的时间间隔,则我认为您有一个具有不同时间单位的不同输入的表单。从这样的输入创建一个字符串将非常简单,而不是在各个时间单位之间进行转换以存储int。
2.它相对紧凑。虽然不像将其转换为一种时间单位并将其存储为int那样紧凑,但比序列化DateInterval对象并存储整个对象要紧凑得多。
我可能忽略了其他更好的选择,但我主要是想分享我先前评论的原因。
如果您最初没有像我假设的那样直接从用户处获得间隔,而是从DateTime :: diff(或我没有想到的其他地方)获得,则仍可以从该对象中获取间隔规范。它具有公共属性,可存储所需的所有部分。类似以下内容应该有效:
function getIntervalSpec(DateInterval $interval) {
    $spec = 'P';
    foreach(['y', 'm', 'd', 'h', 'i', 's'] as $u) {
        if ($u == 'h') $spec .= 'T';
        $spec .= $interval->$u;
        $spec .= $u == 'i' ? 'M' : strtoupper($u);
    }
    return $spec;
}

谢谢!我提出这个问题的原因之一是(尽管我还没有测试过,但已经接近了)format() 方法似乎需要一个格式字符串?如果我不传递格式字符串,它会选择“最佳”的格式吗?如果我可以在序列化时只需使用 ->format() 方法对 DateInterval 进行格式化,然后在构造时使用结果字符串来构建,那将完全符合我的需求。 - Josh Petitt
既然 format() 是为了让你指定输出格式的,那么格式化字符串就不是可选的。我假设你是从用户输入开始,然后使用它来创建 DateInterval。如果是这种情况,我会在创建对象之前存储间隔规范,而不是尝试使用 format() 从对象中获取间隔规范。如果不是这种情况,并且你是使用 DateTime::diff 创建 DateInterval,则应使用 DateInterval 的公共属性创建间隔规范字符串,而不是使用 format() - Don't Panic
@JoshPetitt 我编辑了答案,并提供了一个从DateInterval创建间隔规范字符串的示例。 - Don't Panic
太棒了!我最终使用CarbonInterval自动提供spec()函数。我使用spec()进行序列化,然后可以使用该spec字符串创建DateInterval。 - Josh Petitt

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