将小时范围转换为位串
Convert hour range to a bitstring
我想保存一家公司的营业时间,我正在考虑为此使用位串。
假设公司 A 在星期一上午 8 点到 12 点(中午)和下午 1 点到下午 5 点营业,第 0 天(星期一)
0000 0000 1111 0111 1000 0000
这使得将它保存在数据库中和检索它变得非常容易,而无需进行多重连接等。
然而,它确实让解析用户输入到这个位串变得复杂。
我想给用户 2 select 列表到 select 一个范围,他可以在其中选择开放时间和关闭时间(这里是早上 8 点到中午)。
然后可以复制这 2 select 个列表以创建第二个范围(此处为下午 1 点至下午 5 点)。
如果我可以将一个时间范围解析为一个位串(早上 8 点到中午),那么这些可以很容易地加起来得到一天的位串。
这就是我的问题。 easiest/cleanest 将时间范围解析为位串的方法是什么。
非常感谢任何帮助。
您不将位串存储为字符串,而是存储为整数。然后对它执行按位比较,所以如果你将一天分成 48 个部分,这意味着你需要使用一个 64 位整数,其中最后 16 位只是未使用,或者可以用来表示一天中的天数一周。
位如下
/** times **/
01 00:00 02 00:30 03 01:00 04 01:30 05 02:00 06 02:30 07 03:00 08 03:30
09 04:00 10 04:30 11 05:00 12 05:30 13 06:00 14 06:30 15 07:00 16 07:30
17 08:00 18 08:30 19 09:00 20 09:30 21 10:00 22 10:30 23 11:00 24 11:30
25 12:00 26 12:30 27 13:00 28 13:30 29 14:00 30 14:30 31 15:00 32 15:30
33 16:00 34 16:30 35 17:00 36 17:30 37 18:00 38 18:30 39 19:00 40 19:30
41 20:00 42 20:30 43 21:00 44 21:30 45 22:00 46 22:30 47 23:00 48 23:30
49-57 unused
/** days of week **/
58 Sunday 59 Monday 60 Tuesday 61 Wednesday 62 Thursday 63 Friday 64 Saturday
好的,现在你如何使用它?
如果您想说某家公司周日至周六上午 7 点至上午 8 点和上午 9 点至上午 10 点营业,您可以相加(使用按位或运算符)
将上面的所有 "bits" 和它们进行或运算,这可以通过执行 2 ^ (bit-1)
来完成
$hours = 2^14 | 2^15 | 2^17 | 2^18 | 2^57 | 2^58 | 2^59 | 2^60 | 2^61 | 2^62 | 2^63;
然后做你的查询,你只需做一个按位与。
/** this is checking to see if it's open at 7am and 9am on Thursday **/
$query = (2^14 & 2^17 & 2^61);
/** this will match only if all conditions are true **/
$isOpen = $query & $hours === $query;
/** this will match if some or all conditions are true **/
$isOpen = $query & $hours > 0;
希望这对您有所帮助,让您走上正确的道路。
我想保存一家公司的营业时间,我正在考虑为此使用位串。 假设公司 A 在星期一上午 8 点到 12 点(中午)和下午 1 点到下午 5 点营业,第 0 天(星期一)
0000 0000 1111 0111 1000 0000
这使得将它保存在数据库中和检索它变得非常容易,而无需进行多重连接等。
然而,它确实让解析用户输入到这个位串变得复杂。 我想给用户 2 select 列表到 select 一个范围,他可以在其中选择开放时间和关闭时间(这里是早上 8 点到中午)。 然后可以复制这 2 select 个列表以创建第二个范围(此处为下午 1 点至下午 5 点)。
如果我可以将一个时间范围解析为一个位串(早上 8 点到中午),那么这些可以很容易地加起来得到一天的位串。
这就是我的问题。 easiest/cleanest 将时间范围解析为位串的方法是什么。
非常感谢任何帮助。
您不将位串存储为字符串,而是存储为整数。然后对它执行按位比较,所以如果你将一天分成 48 个部分,这意味着你需要使用一个 64 位整数,其中最后 16 位只是未使用,或者可以用来表示一天中的天数一周。
位如下
/** times **/
01 00:00 02 00:30 03 01:00 04 01:30 05 02:00 06 02:30 07 03:00 08 03:30
09 04:00 10 04:30 11 05:00 12 05:30 13 06:00 14 06:30 15 07:00 16 07:30
17 08:00 18 08:30 19 09:00 20 09:30 21 10:00 22 10:30 23 11:00 24 11:30
25 12:00 26 12:30 27 13:00 28 13:30 29 14:00 30 14:30 31 15:00 32 15:30
33 16:00 34 16:30 35 17:00 36 17:30 37 18:00 38 18:30 39 19:00 40 19:30
41 20:00 42 20:30 43 21:00 44 21:30 45 22:00 46 22:30 47 23:00 48 23:30
49-57 unused
/** days of week **/
58 Sunday 59 Monday 60 Tuesday 61 Wednesday 62 Thursday 63 Friday 64 Saturday
好的,现在你如何使用它?
如果您想说某家公司周日至周六上午 7 点至上午 8 点和上午 9 点至上午 10 点营业,您可以相加(使用按位或运算符)
将上面的所有 "bits" 和它们进行或运算,这可以通过执行 2 ^ (bit-1)
来完成$hours = 2^14 | 2^15 | 2^17 | 2^18 | 2^57 | 2^58 | 2^59 | 2^60 | 2^61 | 2^62 | 2^63;
然后做你的查询,你只需做一个按位与。
/** this is checking to see if it's open at 7am and 9am on Thursday **/
$query = (2^14 & 2^17 & 2^61);
/** this will match only if all conditions are true **/
$isOpen = $query & $hours === $query;
/** this will match if some or all conditions are true **/
$isOpen = $query & $hours > 0;
希望这对您有所帮助,让您走上正确的道路。