V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Kaylar
V2EX  ›  数据库

不同的计时方式怎么用数据库存储查询?公历农历伊斯兰历中国节气

  •  
  •   Kaylar · 2023-09-03 10:28:42 +08:00 · 1280 次点击
    这是一个创建于 449 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我要在数据库存储一些商品、活动每年出现的时间段。有些传统商品或活动用的是本国的传统历法,甚至是节日和节气。而且每年可能有多个时间段,描述也可能用旬这种模糊的词,例如:

    • 农历正月初一到元宵
    • 公历 7 月中旬到 9 月上旬
    • 寒露之后,霜降之前
    • 三九之后,五九之前
    • 农历三月上旬到五月中旬,九月上旬到十一月中旬
    第 1 条附言  ·  2023-09-03 13:22:53 +08:00

    数据库是sqlite3,源数据是固定的。

    我现在就是有每条记录都有 month_start, day_start, month_end, day_end这样的字段,并且有农历字段 lunar_month_start, lunar_day_start, lunar_month_end, lunar_day_end。定期会遍历一遍数据库,将所有农历字段转换成公历并更新到数据库。

    上旬就是 1-10 日,中旬就是11-20日,下旬是21到月底的日期,例如农历九月上旬到十月中旬,存入的数据就是

    month_start day_start month_end day_end lunar_month_start lunar_day_start lunar_month_end lunar_day_end
    9 1 10 20

    今年遍历转换后就变成了

    month_start day_start month_end day_end lunar_month_start lunar_day_start lunar_month_end lunar_day_end
    10 15 12 2 9 1 10 20

    每次查询的时候就只用公历。但是这是只有一个时间段的时候写的方案,没有考虑到多个时间段,也没有考虑到节气和其他历法。

    看前几楼的回复,这种定期转换的方式好像是可行的,现在想知道接下来我该怎么设计表?节气怎么表达?三九五九这种怎么表达?新的历法怎么扩展?想让前端仍然显示源数据的表达方式,又该怎么做,存储源数据的 农历九月上旬到十月中旬 还是运算实现?

    8 条回复    2023-09-04 10:52:10 +08:00
    baobao1270
        1
    baobao1270  
       2023-09-03 11:00:08 +08:00
    无法储存,很多历法都是需要经过天文计算的,单靠本地推算是推不出来的
    建议运营在设置的时候就设置公历日期,每年由运营手动设置
    yingqi7
        2
    yingqi7  
       2023-09-03 12:44:59 +08:00
    只有一个办法,手动维护。有规则的尽量规则化,有源的定期获取,其他的靠填报工具填报
    janus77
        3
    janus77  
       2023-09-03 13:00:50 +08:00
    活动还是手动维护比较好,不光你要考虑历法上面的日期,还有各种临时出现的日期,比如 xx 购物节这些,你觉得这个日期和农历在电商范围内有什么本质上的区别吗?都是指定一段日期然后上活动,而且这个日期随时会变的,比如我说这个节日要上,但是由于各种不可抗力又不上了,这不得人工下架。。。。
    Kaylar
        4
    Kaylar  
    OP
       2023-09-03 13:23:26 +08:00
    @baobao1270 @yingqi7 @janus77 谢谢回复!我 append 了问题
    NoOneNoBody
        5
    NoOneNoBody  
       2023-09-03 15:40:14 +08:00
    统一用公历
    一种方式是用 start,end ,然后加个标注字段,表明该记录适用于什么情况,这个情况应该是可枚举的,如 emun 或字典
    如 start, end, enum 序号:中国-->农历-->中秋节,或者入库只用序号就好了,反正读取时免不了一次匹配

    另一种方式是不要 start,end ,将每天入库,反正最多一年也就 366 条,并记录该天属于哪个节日,例如春节 7 天假期就 7 条记录
    这种方式是直接当天比较,但要描述活动时间区间的话,就需要读取 7 条记录,求 start 和 end

    和前端商量哪种更好用,我个人倾向后者,因为更清晰,不容易错
    julyclyde
        6
    julyclyde  
       2023-09-03 16:34:25 +08:00
    tzdata 可以参考一下,记录的是“某段时间内”有什么具体规定
    bill110100
        7
    bill110100  
       2023-09-04 10:37:36 +08:00
    数据库不支持,很多历法甚至都没有完整的计算公式,需要根据当年天象年年调整。这块最好做在业务端,由业务端进行数据转换到公历,数据库只记录公历。
    农历的话,可以做一套农历和公历转换表,我不知道你的后端语言是哪种,java 的话,java8 新出的 time 模块有完整的时间定义规范,也有人基于规范实现了各国特殊历法,可以参考 Time4J 。
    bill110100
        8
    bill110100  
       2023-09-04 10:52:10 +08:00
    对于后续你的需求,我建议拆分记录表,一张表只记录原始数据,如 start_date ( varchar ):三九之后 ,end_date ( varchar ):五九之前,该数据读到代码里再解析成一组对应年份的公历日期(因为不同年份转化成的公历月份日期都是不一样的),查询时根据需求显示原始数据和解析后的多组时间段数据。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5601 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:47 · PVG 15:47 · LAX 23:47 · JFK 02:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.