记录 时间展示展示方案
[toc]
场景
时间有三种类型:
1、长期
2、具体时间范围
3、周几展示
解决方案
1、长期:使用bool
2、具体范围:startTime-endTime
3、周几展示:使用二进制为1表示周几,例如:0001011表示周一、周二、周四转为十进制为:11,然后将11存储到数据库中,即可。
长期
对于长期展示为true, false则需要在具体时间范围和周几展示选择其一,最后返回true -> 长期
范围
范围使用两个字段:startTime和endTime,返回直接拼接字符串:startTime-endTime
周几
周几展示由于是在数据库中使用二进制逻辑,然后存储十进制,非常节省空间最大的数127,即:周一到周日都需要展示,这里最重要的也就是应用层需要判断前端参数数组:[1,2,4],转为-> 11然后存储,最后需要将11 -> :[1,2,3,4] 然后 1 -> 周一….
解决方案:
// setDayOfWeek 使用二进制位运算将选择的周几表示为一个整数
func setDayOfWeek(days ...int) uint8 {
var result uint8
for _, day := range days {
result |= (1 << uint(day-1))
}
return result
}
// getSelectedDays 将整数表示的选择转换为对应的周几
func getSelectedDays(weekDays uint8) []int {
var result []int
for i := 1; i <= 7; i++ {
if weekDays&(1<<(uint(i-1))) > 0 {
result = append(result, i)
}
}
return result
}
精准查询
如果我们查询某一个的具体的时间,例如:2023-07-30,属于长期展示的肯定需要查询到的,在展示时间范围的也内的也能够查询到:
select * from coupert_base.store_trending where (IsPermanent = true or '2023-08-30' BETWEEN StartDate AND EndDate) order by `Rank` desc LIMIT 0, 100;
但是我们要查询周几展示应该怎么做?
解决方案:
数据库存储的是标记周几的二进制逻辑的十进制数,我们首先需要将2023-07-30转为我们的周几:这天是周末,也就是:7, 然后我们需要将7转为表示二进制的数:1000000, 然后再将其转为十进制,即:64, 然后就可以使用二进制的&运算, SQL如下:
select * from coupert_base.store_trending where (IsPermanent = true or DayOfWeek & 64 = 64 or '2023-07-30' BETWEEN StartDate AND EndDate) order by `Rank` desc LIMIT 0, 100;
这样就可以查询到符合周日的记录了
转换逻辑代码:
package main
import (
"fmt"
"time"
)
// WeekdayToNumber 将 time.Weekday 类型转换为数字周几
func WeekdayToNumber(weekday string) int {
// 注意:time.Weekday 类型的值从 0(周日)到 6(周六)
// 我们将其转换为数字周几(1 表示周一,2 表示周二,...,7 表示周日)
layout := "2006-01-02 15:04:05"
t, _ := time.Parse(layout, weekday)
if int(t.Weekday()) == 0 {
return 7
}
return int(t.Weekday())
}
// 查询是否包含指定的二进制值 对应SQL的代码:DayOfWeek & 64 = 64
func containsBinary(target int, value int) bool {
return target&value == value
}
func main() {
weekDay := WeekdayToNumber("2023-07-30 00:00:00")
fmt.Println("周几:", weekDay)
queryValue := 1 << (weekDay - 1)
fmt.Println("转为二进制逻辑的数::", queryValue)
if containsBinary(75, queryValue) { //75 -> 1001011 表示:"周一 周二 周四 周日"
fmt.Printf("星期%d在记录中", weekDay)
}
//输出:
//周几: 7
//转为二进制逻辑的数:: 64
//星期7在记录中
}