将百度万年历存入自己的数据库

简介Github地址 前言 最近有需要研究阴历和阳历互相转换的问题。因此找到两个库carbon和solarlunar 但是感觉计算出来的总是不太放心,而且也会占用计算资源。我的想法是通过接口获取现成的阴历

Github地址

前言

最近有需要研究阴历和阳历互相转换的问题。因此找到两个库carbon和solarlunar
但是感觉计算出来的总是不太放心,而且也会占用计算资源。我的想法是通过接口获取现成的阴历和阳历数据,存到本地数据库,这样查询的时候一步到位。

方案

我通过百度搜索万年历,抓取网页请求得到百度的一个接口正好可以获取万年历的信息,还是挺全面的。
因此我写代码实现了将百度万年历的数据获取,然后存入数据库的代码。

下面是calendar.go的代码,主要使用gorm创建表,以及写入拉取的数据。

package calendarimport ("encoding/json""errors""fmt""net/http""net/url""strconv""strings""sync""time""golang.org/x/text/encoding/simplifiedchinese""golang.org/x/text/transform""gorm.io/driver/mysql""gorm.io/driver/sqlite""gorm.io/gorm""gorm.io/gorm/logger"
)type (PerpetualCalendar struct {//Status       string `json:"status"`//T            string `json:"t"`//SetCacheTime string `json:"set_cache_time"`Data []PerpetualCalendarData `json:"data"`}PerpetualCalendarData struct {//ExtendedLocation string `json:"ExtendedLocation"`//OriginQuery      string `json:"OriginQuery"`//SiteID           int    `json:"SiteId"`//StdStg           int    `json:"StdStg"`//StdStl           int    `json:"StdStl"`//SelectTime       int    `json:"_select_time"`//UpdateTime       string `json:"_update_time"`//Version          int    `json:"_version"`//Appinfo          string `json:"appinfo"`//CambrianAppid    string `json:"cambrian_appid"`//DispType         int    `json:"disp_type"`//Fetchkey         string `json:"fetchkey"`//Key              string `json:"key"`//Loc              string `json:"loc"`//Resourceid       string `json:"resourceid"`//RoleID           int    `json:"role_id"`//Showlamp         string `json:"showlamp"`//Tplt             string `json:"tplt"`//URL              string `json:"url"`Almanac []PerpetualCalendarAlmanac `json:"almanac"`}PerpetualCalendarAlmanac struct {Id int `gorm:"primarykey"` // 自增主键Animal         string    `json:"animal" gorm:"column:animal;not null;size:4"`                     // 生肖Suit           string    `json:"suit" gorm:"column:suit;not null"`                                // 宜Avoid          string    `json:"avoid" gorm:"column:avoid;not null"`                              // 忌CnDay          string    `json:"cnDay" gorm:"column:cnDay;not null;size:4"`                       // 星期Day            int       `json:"day,string" gorm:"column:day;not null;uniqueIndex:Solar"`         // 阳历日Month          int       `json:"month,string" gorm:"column:month;not null;uniqueIndex:Solar"`     // 阳历月Year           int       `json:"year,string" gorm:"column:year;not null;uniqueIndex:Solar"`       // 阳历年GzDate         string    `json:"gzDate" gorm:"column:gzDate;not null;size:8"`                     // 干支日GzMonth        string    `json:"gzMonth" gorm:"column:gzMonth;not null;size:8"`                   // 干支月GzYear         string    `json:"gzYear" gorm:"column:gzYear;not null;size:8"`                     // 干支年IsBigMonth     string    `json:"isBigMonth" gorm:"-"`                                             // json取数据,忽略gormIsBigMonthBool bool      `gorm:"column:isBigMonth;not null;default:0"`                            // 是否为阴历大月LDate          string    `json:"lDate" gorm:"column:lDate;not null;size:4"`                       // 阴历日,汉字LMonth         string    `json:"lMonth" gorm:"column:lMonth;not null;size:4"`                     // 阴历月,汉字,带'闰'字表示闰月LunarDate      int       `json:"lunarDate,string" gorm:"column:lunarDate;not null;index:Lunar"`   // 阴历日,数字LunarMonth     int       `json:"lunarMonth,string" gorm:"column:lunarMonth;not null;index:Lunar"` // 阴历月,数字LunarYear      int       `json:"lunarYear,string" gorm:"column:lunarYear;not null;index:Lunar"`   // 阴历年,数字ODate          time.Time `json:"oDate" gorm:"column:oDate;not null"`                              // ODate.Local(),阳历当天0点Term           string    `json:"term,omitempty" gorm:"column:term;not null"`                      // 如'除夕','万圣节','三伏'等Desc           string    `json:"desc,omitempty" gorm:"column:desc;not null"`                      // 如'腊八节','下元节'等Type           string    `json:"type,omitempty" gorm:"column:type;not null;size:2"`               // 各种和节日有关的类型Value          string    `json:"value,omitempty" gorm:"column:value;not null"`                    // 如'国际残疾人日'等Status         int       `json:"status,string,omitempty" gorm:"column:status;not null;default:0"` // 0 工作日,1 休假,2 上班,3 周末}
)func (PerpetualCalendarAlmanac) TableName() string {return "perpetualCalendarAlmanac"
}// GetPerpetualCalendar 返回[前一个月,本月,后一个月]的数据
func GetPerpetualCalendar(year, mouth int) ([]PerpetualCalendarAlmanac, error) {u := url.Values{}u.Add("tn", "wisetpl")u.Add("format", "json")u.Add("resource_id", "39043") // 这个用浏览器请求后得到的u.Add("query", fmt.Sprintf("%d年%d月", year, mouth))u.Add("t", strconv.FormatInt(time.Now().UnixMilli(), 10))urls := "https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?" + u.Encode()resp, err := http.Get(urls) // 百度这个接口可能现在请求速度,所以可能报错if err != nil {return nil, err}defer resp.Body.Close()var ret PerpetualCalendar // 需要将gbk转为utf8err = json.NewDecoder(transform.NewReader(resp.Body, simplifiedchinese.GBK.NewDecoder())).Decode(&ret)if err != nil {return nil, err}if len(ret.Data) != 1 { // 该数组目前只会有一个return nil, errors.New("get Data error")}for i, v := range ret.Data[0].Almanac {// 赋值大月ret.Data[0].Almanac[i].IsBigMonthBool = v.IsBigMonth == "1"if v.Status == 0 && (v.CnDay == "六" || v.CnDay == "日") {ret.Data[0].Almanac[i].Status = 3 // 不是特殊类型,且为周末则赋值}}return ret.Data[0].Almanac, nil
}func SaveCalendar(dsnSrc string) error {ts := time.Now()defer func() {fmt.Println(time.Since(ts))}()iDsn := strings.Index(dsnSrc, ":")if iDsn < 0 {return errors.New("dsn error")}var gormOpen gorm.Dialectorswitch strings.ToLower(dsnSrc[:iDsn]) {case "mysql":gormOpen = mysql.Open(dsnSrc[iDsn+1:])case "sqlite":gormOpen = sqlite.Open(dsnSrc[iDsn+1:])default:return errors.New("just support mysql or sqlite")}db, err := gorm.Open(gormOpen, &gorm.Config{Logger: logger.Default.LogMode(logger.Silent),})if err != nil {return err}res := db.Exec("DROP table if exists " + PerpetualCalendarAlmanac{}.TableName())if res.Error != nil {return res.Error}// 每次重建数据表err = db.AutoMigrate(PerpetualCalendarAlmanac{})if err != nil {return err}// 起止时间按照百度万年历得到start := time.Date(1900, time.February, 1, 0, 0, 0, 0, time.Local)end := time.Date(2050, time.December, 1, 0, 0, 0, 0, time.Local)wg := sync.WaitGroup{}// 由于每次查询包含前一个月,当月,下个月,因此每次都增加3个月进行查询for ; start.Before(end); start = start.AddDate(0, 3, 0) {wg.Add(1)y, m, _ := start.Date()go func(y, m int) {defer wg.Done()for { // 使用协程并发请求,提高速度,出现错误时重试data, err := GetPerpetualCalendar(y, m)if err != nil {fmt.Println("GetPerpetualCalendar", y, m, err)continue // 报错重试,直到成功}res := db.Create(&data)if res.Error != nil {fmt.Println("Create", y, m, res.Error)continue // 报错重试,直到成功}break}}(y, int(m))}wg.Wait()return nil
}

下面是main.go,根据传入的参数,选择是保存在mysql还是sqlite中。

package mainimport (calendar "interesting/perpetual_calendar"
)func main() {dsn := "mysql:user:pass@tcp(127.0.0.1:3306)/janbar?charset=utf8mb4&parseTime=True&loc=Local"//dsn := "sqlite:test.db"err := calendar.SaveCalendar(dsn)if err != nil {panic(err)}
}

结果展示

如下图所示,是存入的数据,已经为阳历年月日创建唯一联合索引,阴历年月日因为存在闰月会重复,因此只创建了联合索引。

查询语句可以按照下面的来做。大部分属性已经按照我的理解写到注释里面了,可以结合百度的万年历看看,展示在哪个位置吧。

查询阳历 2021-09-16 号的数据,结果有对应的阴历情况
SELECT *FROM perpetualCalendarAlmanac WHERE year=2021 AND month=9 AND day=16查询阴历 2021-09-03 号的数据,结果有对应阳历的情况
SELECT *FROM perpetualCalendarAlmanac WHERE lunarYear=2021 AND lunarMonth=9 AND lunarDate=3

总结

这个接口调用,和存数据没啥难度。主要是让我加深对gorm等库的使用。
当然最主要是我想实现按照阴历定时的cron规则,结合cron库来搞。

作者:janbar

出处:janbar - 博客园

本文版权归作者和博客园所有,欢迎转载,转载请标明出处。喜欢我的文章请 [关注我] 吧。

如果您觉得本篇博文对您有所收获,可点击 [推荐] 并 [收藏] ,或到右侧 [打赏] 里请我喝杯咖啡,非常感谢。

Tags:自己的 存入 万年历 数据库

www.jcdi.cn
www.sobd.cc
www.bdsoba.com

将百度万年历存入自己的数据库相关推荐

  1. php百度人脸识别做登陆,php调用百度人脸识别接口查询数据库人脸信息实现验证登录功能...

    博主在进行鼎食城毕业设计时,需要实现一个人脸识别登录功能,想到可以利用百度的人脸识别接口来完成,于是便去下载了百度的识别SDK,我用的是PHP,需要的的可以去下载其他版本,以下是识别效果: 用户在开始 ...

  2. 微信小程序图片无法存入云开发数据库,求解决

    微信小程序图片无法存入云开发数据库,求解决 上传图片的js代码片段 上传图片的js代码片段 上传图片的js代码片段,觉得自己代码的没错,也能打印出来上传的图片地址,但是发现并没有存进数据库,求大神指点 ...

  3. 百度网盘BaiduYunCacheFileV0.db数据库研究

    最近研究了一下百度网盘的本地数据库文件:BaiduYunCacheFileV0.db,设计类似于网盘的数据库时可以借鉴一下. 下面是自己整理的数据库注释,有可能不正确,尤其是fid . CREATE ...

  4. php mysql表情符号_php + mysql 存入表情 【如何转义emoji表情,让它可以存入utf8的数据库】...

    方法1:base_encode64 这种方法是可以,但是旧数据没有经过encode操作,取数据的时候如果统一进行decode的话,旧数据会丢失的. 1 方法2:urlencode 这个似乎可以,对没有 ...

  5. php 人脸识别接口,php调用百度人脸识别接口查询数据库人脸信息实现验证登录功能...

    博主在进行鼎食城毕业设计时,需要实现一个人脸识别登录功能,想到可以利用百度的人脸识别接口来完成,于是便去下载了百度的识别SDK,我用的是PHP,需要的的可以去下载其他版本,以下是识别效果: 用户在开始 ...

  6. c 将图片存入到mysql数据库中_如何将图片转换存入到数据库中,并从数据库中取出转换成图片...

    有时候我们想把图片存入到数据库中,尽管这不是一种明智的选择,但有时候还是不得以会用到,下面说说将图片转换成byte[]数组存入到数据库中去,并从数据库中取出来转换成图像显示出来. 首先,我们要把图片存 ...

  7. 将DataFrame格式的数据存入到mysql数据库中

    因为最近频繁操作数据库,特别是写入数据比较麻烦.在DataFrame格式或者是Series格式的数据处理之后,总是会面临写入数据,迫不得已只能进行格式转换,搜索过程中发现了to_sql()函数,就百度 ...

  8. 利用python编写爬虫程序,从招聘网站上爬取数据,将数据存入到MongoDB数据库中,将存入的数据作一定的数据清洗后做数据分析,最后将分析的结果做数据可视化

    教程演示 创建爬虫项目 编写需要爬取的字段(items.py) 编写spider文件(wuyou.py) 编写数据库连接(pipelines.py) 编写反爬措施(settings.py) Mongo ...

  9. java读取word中的表格并存入到mysql数据库中实例

    将D://word_export.doc(word2003)文件中表格数据读取出来并存入到数据库中.表格数据如下图所示: 20064001 刘景玉 1987-01-25 男 河南商丘 20064002 ...

  10. 百度网盘 备份mysql数据库_利用百度云免费备份SQL数据库

    我们开发了一个会员管理系统,随着使用的人越来越多,异地备份数据库就显得十分重要,万一硬盘出问题了怎么办呢.所以就着手做这个工作. 首先呢,找到了几个专门用来提供备份数据库的网站,一年好几百,好贵.放弃 ...

最新文章

  1. python基础知识面试题-python的一些基本概念知识和面试题
  2. 独立开发者:新手做2D手游该用哪些工具?
  3. 留下方便自己找,,,求导
  4. 良好的代码风格养成记
  5. SAP UI技术演进过程
  6. CodeForces - 225C. Barcode(DP)
  7. java里面运行js_在java中利用rhino执行javascript
  8. NDK-r14b + FFmpeg-release-3.4 linux下编译FFmpeg
  9. 饿了么超时20分钟_饿了么回应“多等5分钟”,网友气炸了
  10. 清华学霸尹成Python爬虫视频 [MP4] (33.96G)
  11. python 直方图匹配_python库skimage 绘制直方图;绘制累计直方图;实现直方图匹配(histogram matching)...
  12. 上兴远程控制使用及分析
  13. Android 仿微博客户端 ViewPaper
  14. vue中使用图片裁切器
  15. SqlServer数据库性能优化详解
  16. 交大研究生去日本签证攻略
  17. 宋第一状元宰相吕蒙正三赋
  18. html ico 图片 无效,favicon.ico不显示的原因分析和解决办法
  19. 【待写】x265:CRF、ABR、CQP码控模式性能测试
  20. dva model里面的effects函数可以调用effects函数

热门文章

  1. python编码无法使用turtle库_使用Turtle库教Python
  2. 伺服位置模式参数设置
  3. 电信基站大区对应表_铁塔基站直流电能表 直流计量表
  4. 性能优化之电量和网络
  5. siamfc-pytorch代码讲解(二):trainsiamfc
  6. mybatis批量导入
  7. php 批量采集 邮箱,万能全网邮箱批量采集工具按照关键字搜索邮箱教程
  8. 数据库课程设计 论坛系统—— 系统详细设计说明书
  9. Duplicate entry '' for key 'username'
  10. libusb 串口 android,libusb 根据设备的serialnumber来打开