如何使用位字段存储一周中的几天?

um6iljoc  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(666)

我正在重新分解一个应用程序,其中一个数据库表以列的形式存储一周中的几天。每天可以是“开”或“关”。
开和关的概念使我认为这些数据可以更简洁地表示为位。但我以前从未将原始位用作数据类型。
应用程序是用php编写的。我见过一些用于存储头值的位。然后是“helper”常量( HEADER_X_FORWARDED_ALL 以及 HEADER_X_FORWARDED_ALL 作为所有正在使用的报头的“预配置”,或用于类似aws elb的环境的子集(其中一些报头未发送,因此“关闭”)。
所以我有几个问题,用这个数据类型来表示一周中的几天:
如何在mysql中存储最后的位值?如列数据类型、长度等。
我该如何检查一天是“开”的?如果我有价值的话 0b0100000 ,如何使用位运算符确定星期二为“开”?
如何“设置”在数据库中保留值的天数?因此,如果ui中有复选框将值作为数组提交,我将如何转换如下内容:

Array
(
    [days] => Array
        (
            [Monday] => 0
            [Tuesday] => 1
            [Wednesday] => 0
            [Thursday] => 0
            [Friday] => 0
            [Saturday] => 0
            [Sunday] => 0
        )
)

…有点像 0b0100000 ,再次使用位运算符?
如果有人能给我指出正确的方向,让我开始在php中使用位值,我将非常感激!

rdrgkggo

rdrgkggo1#

您可以存储所选日期的十进制值。作为一个基本的例子:

/**
 * Keys are ISO-8601 numeric representation
 * of the days of the week
 */
$days = [
    1 => 0b0000001, // Monday    =>  1
    2 => 0b0000010, // Tuesday   =>  2
    3 => 0b0000100, // Wednesday =>  4
    4 => 0b0001000, // Thursday  =>  8
    5 => 0b0010000, // Friday    => 16
    6 => 0b0100000, // Saturday  => 32
    7 => 0b1000000, // Sunday    => 64
];

您只需循环并检查是否在值中设置了一天的位(按位and):

// The value you'd store in your database
$mondayToFriday = 31; // 1 + 2 + 4 + 8 + 16

foreach ($days as $n => $v) {

    /**
     * Get the day's name using strftime (has locale capability)
     * strtotime("Sunday +n days") would work with ISO-8601 day
     * numbers or PHP's date("w") (0 - 6 / Sunday - Saturday)
     */
    $day = strftime("%A", strtotime("Sunday +{$n} days"));

    echo "{$day}: " . (($v & $mondayToFriday) ? "Y" : "N") . PHP_EOL;

}

至于您的复选框,您只需从每天的状态(0或1)构建二进制字符串,并使用 bindec() (它们在数组中出现的顺序很重要,您需要确保它们正确地Map到相应的日值)。
根据您的示例输入,以及本示例中的天数,以下操作将起作用:

$dec = bindec(strrev(implode("", $input["days"])));

希望这能把你推向正确的方向。

下面是一个例子

相关问题